{
  "coverage": {
    "files_failed": 0,
    "files_scanned": 4,
    "files_skipped": 0,
    "rules_run": 935
  },
  "crypto": {
    "coverage": {
      "algorithms": 65,
      "files_scanned": 2,
      "files_skipped": 0,
      "test_files": 1
    },
    "uses": [
      {
        "algorithm": "MD5",
        "assessment": "broken",
        "evidence": "return jsonify({\"receipt\": hashlib.md5(order_id.encode()).hexdigest()})",
        "kind": "hash",
        "line": 26,
        "note": "Collisions are practical. Not suitable for signatures, integrity against an adversary, or password storage.",
        "path": "app.py"
      }
    ]
  },
  "dependencies": {
    "coverage": {
      "advisories": 288353,
      "bundle_built_at": "2026-10-09T06:30:43Z",
      "bundle_digest": "sha256:e9866473b379d6bd61939709c3cd0efbb50de8e84591865617a39c81a65f0f50",
      "components_checked": 2
    },
    "findings": [
      {
        "aliases": [
          "CVE-2026-27205",
          "PYSEC-2026-2151"
        ],
        "cvss": 2.3,
        "cwes": [
          "CWE-524"
        ],
        "direct": true,
        "epss": 0.00423,
        "fixed_in": [
          "3.1.3"
        ],
        "id": "GHSA-68rp-wp8r-4726",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/flask@2.2.2",
        "remediation": "Upgrade flask to 3.1.3, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "LOW",
        "summary": "Flask session does not add `Vary: Cookie` header when accessed in some ways"
      },
      {
        "aliases": [
          "CVE-2023-30861",
          "PYSEC-2023-62"
        ],
        "cvss": 7.5,
        "cwes": [
          "CWE-539"
        ],
        "direct": true,
        "epss": 0.01261,
        "fixed_in": [
          "2.2.5"
        ],
        "id": "GHSA-m2qf-hxjv-5gpq",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/flask@2.2.2",
        "remediation": "Upgrade flask to 2.2.5, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "HIGH",
        "summary": "Flask vulnerable to possible disclosure of permanent session cookie due to missing Vary: Cookie header"
      },
      {
        "aliases": [
          "CVE-2026-27199",
          "PYSEC-2026-2320"
        ],
        "cvss": 6.3,
        "cwes": [
          "CWE-67"
        ],
        "direct": true,
        "epss": 0.00543,
        "fixed_in": [
          "3.1.6"
        ],
        "id": "GHSA-29vq-49wr-vm6x",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 3.1.6, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "MEDIUM",
        "summary": " Werkzeug safe_join() allows Windows special device names"
      },
      {
        "aliases": [
          "CVE-2024-34069",
          "PYSEC-2026-2043"
        ],
        "cvss": 7.5,
        "cwes": [
          "CWE-352"
        ],
        "direct": true,
        "epss": 0.03397,
        "fixed_in": [
          "3.0.3"
        ],
        "id": "GHSA-2g68-c3qc-8985",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 3.0.3, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "HIGH",
        "summary": "Werkzeug debugger vulnerable to remote execution when interacting with attacker controlled domain"
      },
      {
        "aliases": [
          "CVE-2026-21860",
          "PYSEC-2026-2044"
        ],
        "cvss": 6.3,
        "cwes": [
          "CWE-67"
        ],
        "direct": true,
        "epss": 0.00475,
        "fixed_in": [
          "3.1.5"
        ],
        "id": "GHSA-87hc-h4r5-73f7",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 3.1.5, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "MEDIUM",
        "summary": " Werkzeug safe_join() allows Windows special device names with compound extensions"
      },
      {
        "aliases": [
          "CVE-2024-49766",
          "PYSEC-2026-2045"
        ],
        "cvss": 6.3,
        "cwes": [
          "CWE-22"
        ],
        "direct": true,
        "epss": 0.00776,
        "fixed_in": [
          "3.0.6"
        ],
        "id": "GHSA-f9vj-2wh5-fj8j",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 3.0.6, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "MEDIUM",
        "summary": "Werkzeug safe_join not safe on Windows"
      },
      {
        "aliases": [
          "CVE-2026-102598"
        ],
        "cvss": 6.3,
        "cwes": [
          "CWE-67"
        ],
        "direct": true,
        "epss": 0.00368,
        "fixed_in": [
          "3.1.9"
        ],
        "id": "GHSA-g6x2-hccm-hh4m",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 3.1.9, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "MEDIUM",
        "summary": "Werkzeug safe_join() allows Windows special device names"
      },
      {
        "aliases": [
          "CVE-2025-66221",
          "PYSEC-2026-2046"
        ],
        "cvss": 5.3,
        "cwes": [
          "CWE-67"
        ],
        "direct": true,
        "epss": 0.00511,
        "fixed_in": [
          "3.1.4"
        ],
        "id": "GHSA-hgf8-39gv-g3f2",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 3.1.4, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "MEDIUM",
        "summary": "Werkzeug safe_join() allows Windows special device names"
      },
      {
        "aliases": [
          "CVE-2023-46136",
          "PYSEC-2023-221"
        ],
        "cvss": 8,
        "cwes": [
          "CWE-400",
          "CWE-407",
          "CWE-787"
        ],
        "direct": true,
        "epss": 0.01072,
        "fixed_in": [
          "2.3.8"
        ],
        "id": "GHSA-hrfv-mqp8-q5rw",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 2.3.8, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "HIGH",
        "summary": "Werkzeug DoS: High resource usage when parsing multipart/form-data containing a large part with CR/LF character at the beginning"
      },
      {
        "aliases": [
          "CVE-2023-23934",
          "PYSEC-2023-57"
        ],
        "cvss": 2.6,
        "cwes": [
          "CWE-20"
        ],
        "direct": true,
        "epss": 0.00507,
        "fixed_in": [
          "2.2.3"
        ],
        "id": "GHSA-px8h-6qxv-m22q",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 2.2.3, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "LOW",
        "summary": "Incorrect parsing of nameless cookies leads to __Host- cookies bypass"
      },
      {
        "aliases": [
          "CVE-2024-49767",
          "PYSEC-2026-1860",
          "PYSEC-2026-3417"
        ],
        "cvss": 6.9,
        "cwes": [
          "CWE-400",
          "CWE-770"
        ],
        "direct": true,
        "epss": 0.01095,
        "fixed_in": [
          "3.0.6"
        ],
        "id": "GHSA-q34m-jh98-gwm2",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 3.0.6, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "MEDIUM",
        "summary": "Werkzeug possible resource exhaustion when parsing file data in forms"
      },
      {
        "aliases": [
          "CVE-2023-25577",
          "PYSEC-2023-58"
        ],
        "cvss": 7.5,
        "cwes": [
          "CWE-770"
        ],
        "direct": true,
        "epss": 0.0142,
        "fixed_in": [
          "2.2.3"
        ],
        "id": "GHSA-xg9f-g7g7-2323",
        "manifest": "requirements.txt",
        "purl": "pkg:pypi/werkzeug@2.2.2",
        "remediation": "Upgrade werkzeug to 2.2.3, the earliest release this advisory does not list as affected; check any later version against the advisory before choosing it. For a transitive dependency, upgrade the package that pulls it in or add an override, then regenerate the lock file.",
        "severity": "HIGH",
        "summary": "High resource usage when parsing multipart form data with many fields"
      }
    ]
  },
  "findings": [
    {
      "column": 1,
      "confidence": "low",
      "cwe": [
        306,
        862
      ],
      "end_line": 20,
      "fingerprint": "sha256:dbc1924bc2eb8c823dff89294261c3a105cd7789eaa420acca63d29d31c3a661",
      "line": 16,
      "message": "REVIEW: This view has no authentication applied at the view. Global middleware, URL wrappers or handler helpers may still protect it. Confirm the actual route and object or function permissions before confirming anonymous access.",
      "owasp": [
        "A01:2021"
      ],
      "path": "app.py",
      "remediation": "Protect the view with an authentication decorator such as flask_login's @login_required (or Django's login_required), then check that the signed-in user may access the specific record.",
      "severity": "high",
      "snippet": "@app.get(\"/orders\") ...",
      "title": "REVIEW: View lacks an authentication requirement"
    },
    {
      "column": 1,
      "confidence": "low",
      "cwe": [
        306
      ],
      "end_line": 20,
      "fingerprint": "sha256:728ed3927b77bbf90c9dc4e9bc1ae375b781c21ada95032c26baeedcffd9ad5f",
      "line": 16,
      "message": "REVIEW: This route declares no authentication dependency. Application or router dependencies, middleware and checks in the handler may still enforce access. Verify effective registration and permissions before confirming forced browsing or authorisation bypass.",
      "owasp": [
        "A01:2021"
      ],
      "path": "app.py",
      "remediation": "Declare an authentication dependency on the route (viewer = Depends(current_user)) or on the APIRouter, and use the authenticated identity to scope the data returned.",
      "severity": "high",
      "snippet": "@app.get(\"/orders\") ...",
      "title": "REVIEW: FastAPI route lacks an authentication dependency"
    },
    {
      "column": 12,
      "confidence": "medium",
      "cwe": [
        89
      ],
      "end_line": 19,
      "fingerprint": "sha256:5428c3e8e9c5121ec6a3829849ea58582a8fe09961fceb593bef5a84ce058e02",
      "flow": [
        {
          "label": "untrusted input",
          "line": 18,
          "snippet": "request.args.get(\"customer\", \"\")"
        },
        {
          "label": "reaches",
          "line": 19,
          "snippet": "connect().execute(f\"SELECT id, total FROM orders WHERE customer = '{customer}'\")"
        }
      ],
      "line": 19,
      "message": "A SQL statement is assembled with string concatenation, formatting or an f-string from data that reaches the function untrusted. The database receives attacker-controlled syntax rather than data.",
      "owasp": [
        "A03:2021"
      ],
      "path": "app.py",
      "remediation": "Pass request values to the database as bound parameters, for example cursor.execute(\"SELECT * FROM orders WHERE id = %s\", (order_id,)), and never format them into the SQL string.",
      "severity": "critical",
      "snippet": "connect().execute(f\"SELECT id, total FROM orders WHERE customer = '{customer}'\")",
      "title": "SQL query built from untrusted input"
    },
    {
      "column": 32,
      "confidence": "medium",
      "cwe": [
        328,
        327
      ],
      "end_line": 26,
      "fingerprint": "sha256:3c4329c8fac0a21dfe8a5ca4854d8cfebbae1782632af08a94f76a9dd6e34ca8",
      "line": 26,
      "message": "hashlib.md5, hashlib.sha1, hashlib.new('md5'|'sha1'), PyCryptodome MD5/SHA1 or cryptography's hashes.MD5/SHA1 are used without marking the call as non-security. Both algorithms have practical collision attacks: a digest used to identify, sign, deduplicate or protect sensitive data can be forged or matched by an attacker.",
      "owasp": [
        "A02:2021"
      ],
      "path": "app.py",
      "remediation": "Use SHA-256 or stronger (hashlib.sha256, hashlib.blake2b). For passwords use a password hashing function (argon2, scrypt, bcrypt, PBKDF2). Where MD5 or SHA-1 is required for a non-security checksum, pass usedforsecurity=False so the intent is explicit.",
      "severity": "medium",
      "snippet": "hashlib.md5(order_id.encode())",
      "title": "MD5 or SHA-1 used where a collision-resistant hash is expected"
    },
    {
      "column": 1,
      "confidence": "medium",
      "cwe": [
        494
      ],
      "end_line": 1,
      "fingerprint": "sha256:ced7670289fff0791da8749d2cb53e967342689b0f4857bf4c538318529ec157",
      "line": 1,
      "message": "The requirement is pinned to a version but carries no --hash, so pip will install whatever the index serves under that version rather than the artefact that was reviewed.",
      "owasp": [
        "A08:2021"
      ],
      "path": "requirements.txt",
      "remediation": "Record a hash for every pinned requirement and install with --require-hashes, so pip installs exactly the reviewed artefacts.",
      "severity": "medium",
      "snippet": "requirements.txt",
      "title": "Pinned requirement without a hash"
    }
  ],
  "inventory": {
    "components": [
      {
        "direct": true,
        "purl": "pkg:pypi/flask@2.2.2"
      },
      {
        "direct": true,
        "purl": "pkg:pypi/werkzeug@2.2.2"
      }
    ],
    "manifests": [
      "requirements.txt"
    ]
  },
  "provenance": {
    "advisory_built_at": "2026-10-09T06:30:43Z",
    "advisory_digest": "sha256:e9866473b379d6bd61939709c3cd0efbb50de8e84591865617a39c81a65f0f50",
    "finished_at": "2026-10-10T05:58:48.376912Z",
    "include_tests": false,
    "passes": [
      {
        "name": "sast",
        "status": "completed"
      },
      {
        "name": "iac",
        "status": "completed"
      },
      {
        "name": "sca",
        "status": "completed"
      },
      {
        "name": "secrets",
        "status": "completed"
      },
      {
        "name": "sbom",
        "status": "completed"
      },
      {
        "name": "cbom",
        "status": "completed"
      },
      {
        "name": "aibom",
        "reason": "separate aibom command",
        "status": "not_requested"
      },
      {
        "name": "malicious",
        "reason": "separate malicious package check",
        "status": "not_requested"
      }
    ],
    "started_at": "2026-10-10T05:58:43.201333Z"
  },
  "secrets": {
    "coverage": {
      "detectors": 56,
      "files_scanned": 6,
      "files_skipped": 0
    },
    "findings": [
      {
        "column": 20,
        "description": "Credential assigned in source",
        "digest": "sha256:cd27c4c435d5d9ce",
        "entropy": 5.1,
        "line": 4,
        "path": "settings.py",
        "preview": "pk_s******p0Js",
        "remediation": "Revoke or rotate this credential at its provider first: deleting it from the file leaves it in every clone and in history. Issue a replacement, keep it in a secret store read at run time, then remove the value from history (git filter-repo or BFG) and force push.",
        "severity": "medium"
      }
    ]
  }
}