Files
shopdb-flask/scripts/vulnerability-allowlist.json
cproudlock 794bb4668f
Some checks failed
CI / naming (push) Successful in 3s
CI / frontend (push) Successful in 13s
CI / migrations-mysql (push) Successful in 41s
CI / backend (push) Has been cancelled
Add vulnerability scanning on top of the SBOM
The SBOM was generated and installed onto every server, and nothing read it.
"Are we exposed to this advisory" was still a person going and looking, which
meant it happened when somebody remembered to.

scripts/scan_sbom.py queries OSV.dev by purl - no account, no API key, no agent,
no vulnerability database to maintain on a box that cannot reach the internet.
The SBOM is already the input OSV wants, so this is a lookup against what
shipped rather than a second scan of the tree that could disagree with it.

Three decisions worth recording:

Shipped and build-only findings are both reported, but only shipped ones can
fail a build. Two thirds of the components here are build tooling the SBOM
already marks scope 'excluded', and the highest-severity match in the whole tree
today is a CRITICAL against the test runner. A gate that fails a release over
that trains everybody to bypass it, and then it catches nothing.

Severity is taken from the advisory, never derived. Where there is only a CVSS
vector the report says UNKNOWN, which is shown and never gates. A guessed score
is worse than an honest gap because somebody would act on it.

The allowlist is a record rather than a mute button: each entry carries the
reason, the accepter, the date, and what would invalidate the reasoning. The
first entry is a worked example - a PyJWT algorithm-confusion advisory that
needs both mixed algorithm families and a raw JSON JWK as the key, and this
application configures neither.

The report ends with a per-component upgrade rollup, since that is the part
somebody acts on. A target on a different major version is labelled rather than
listed beside patch bumps as though the two cost the same.

Current state: 8 shipped components have fixes available, none of them
exploitable through a path this application opens today.
2026-08-29 17:18:58 -04:00

28 lines
1.5 KiB
JSON

{
"_comment": [
"Advisories reviewed and accepted, with the reason and the date.",
"This is a RECORD, not a mute button: an entry says somebody looked at",
"the advisory and worked out why it does not apply here. Anyone can",
"re-read the reason and disagree.",
"",
"An entry needs an id, a reason that names the precondition that is",
"absent, who accepted it, and when. 'reviewuntil' is when the reasoning",
"should be checked again - a reason stops being true when the code that",
"made it true changes.",
"",
"Do NOT add an entry to make a build pass. Upgrading the dependency is",
"almost always cheaper than defending a decision to skip it."
],
"accepted": [
{
"id": "GHSA-xgmm-8j9v-c9wx",
"component": "pyjwt",
"reason": "Needs a verifier configured with BOTH symmetric and asymmetric algorithms and a raw JSON JWK passed as key=. Neither is present: auth goes through flask-jwt-extended with no JWT_ALGORITHM or JWT_DECODE_ALGORITHMS override anywhere in the tree, so it is HS256-only, and the key is the JWT_SECRET_KEY string. Upstream rates the attack complexity High for exactly this reason. Upgrade to pyjwt 2.13.0 anyway at the next dependency bump; this entry only says it is not urgent.",
"acceptedby": "DT team, reference site",
"accepted": "2026-08-29",
"reviewuntil": "2026-11-29",
"invalidatedby": "Setting JWT_ALGORITHM or JWT_DECODE_ALGORITHMS to anything asymmetric, or moving to SSO-issued tokens verified against a JWK."
}
]
}