fix(security): close the 20 high dependency CVEs, and unbreak the gates that were hiding behind them - #179
Conversation
…y gate Security Gate now reports DEP_HIGH=20 and fails. It was green on this same commit as recently as 2026-09-13; nothing here changed, the advisory data did. Reproduced locally against origin/main's lockfile with the same scanner: 20 HIGH, 19 of them @xmldom/xmldom and 1 js-cookie — exactly the count the gate reports. @xmldom/xmldom carries a batch of CVEs (CVE-2026-83605 through -83619, requireWellformed bypasses) that patch the 0.8 and 0.9 branches independently: 0.8.x is fixed in 0.8.15, 0.9.x in 0.9.12. The existing override pinned the floor at >=0.8.13, which is inside the vulnerable range, and both 0.8.13 and 0.9.10 were installed. Each branch gets its own ceiling so 0.8 consumers are not forced onto 0.9, which is an API break. js-cookie 3.0.6 -> >=3.0.7 for CVE-2026-46625. Lockfile regenerated with --lockfile-only; it now resolves @xmldom/xmldom@0.8.15, @xmldom/xmldom@0.9.12 and js-cookie@3.0.8. Rescanned: 20 HIGH before, 0 after. No advisory was ignored and no threshold moved.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Files
|
PR Checks Summary
✅ All checks passed! Ready for review. |
…tten for
The gate reads pnpm.auditConfig.ignoreCves from 'package.json', but the step
runs with working-directory: frontend, so it was reading
frontend/package.json — whose auditConfig is empty. The curated list is in
the ROOT package.json. The gate therefore applied no ignores at all and
re-blocked on advisories already assessed and accepted, which is the exact
failure its own comment says it was added to prevent. Now reads
${GITHUB_WORKSPACE}/package.json, so there is one list and it is the
curated one.
Adds CVE-2026-19693 (GHSA-7pqw-9j4j-h8q3, extract-zip symlink path
traversal) beside CVE-2026-56876, which is the SAME package and the same
class of advisory, already accepted. Neither has a fix: both report
first_patched_version NONE against <= 2.0.1, and 2.0.1 is npm latest, so
there is nothing to upgrade to. extract-zip reaches the tree only through
devDependencies — @lhci/cli and @wdio/appium-service, both via
@puppeteer/browsers — unpacking archives CI fetches itself, and is never
shipped.
Every entry's rationale now sits in the workflow beside the code that
consumes it, with the rule that an advisory may be ignored only while it has
no published fix, and the command to re-check.
Verified against this PR's own audit report: the list filters exactly one
advisory, the extract-zip high. critical=0 high=0 moderate=12 low=3 with it,
critical=0 high=1 moderate=12 low=3 without. No moderate or low is newly
suppressed.
CI has been red since MinIO removed minio/minio from Docker Hub. The
Accessibility E2E job fails at 'Start nself backend stack':
minio Error pull access denied for minio/minio, repository does not
exist or may require 'docker login'
The Hub API now answers {"message":"object not found"} for the repository
and every tag returns 401, to anonymous and authenticated requests alike,
so a docker login step would not fix it. quay.io/minio/minio is MinIO's own
registry and serves :latest anonymously.
Verified by resolving the CI stack exactly as the workflow does (.env.dev
plus the CI computed vars) and checking each image: all 9 resolve, where
minio was previously the only failure.
Also updates the deploy compose files, the k8s manifest, the CLI services
wiki page and the storage issue template, which carried the same dead image.
backend/docker-compose.yml is marked GENERATED BY nself build. Editing it by
hand is a deliberate deviation, taken because main is red today and the
generator fix (nself-org/cli#424) is not released yet. The durable fix is to
regenerate this file once that ships. Separately, a generated compose file
should not be tracked at all under the org rule; that is left alone here
rather than de-tracked in a CI fix.
…po tracks on purpose
The two gates in this workflow contradicted each other. Doc-Sync carves out
backend/docker-compose.yml by name — 'tracked for CI E2E provisioning
(nself start --skip-build needs the file at checkout)' — while the Generated
File Gate refused every commit that touched it. The file could be kept but
never corrected, which is how it stayed pinned to a MinIO image Docker Hub
had deleted, and why this PR's own fix could not land.
The carve-out is verified, not blanket. This gate exists to stop generated
files carrying plaintext credentials into a public repo (the ntask incident:
a generated compose with the postgres password, Hasura admin secret and JWT
keys). That protection is kept exactly: all 21 credential-shaped keys in this
file are ${...} references today, and the gate now asserts that on every
commit — a literal value fails it with the offending lines printed.
Verified both directions locally: the gate passes on this PR's diff, and
replacing one ${POSTGRES_PASSWORD} with a literal makes it fail and name the
line. Every other generated file is refused exactly as before.
Combined with #178 — they were blocking each otherTwo PRs, each held red by the fix in the other:
Neither can go green alone. #178's two commits are now on this branch; #178 is closed in favour of this PR. What is on the branch now
The one remaining high, and why it is accepted rather than fixedAfter the override fix, There is nothing to upgrade to. It reaches the tree only through devDependencies — Verified the ignore list filters exactly one advisory and widens nothing:
Every entry's rationale now lives in the workflow next to the code that consumes it, with the standing rule that an advisory may be ignored only while it has no published fix, and the |
Security Scan Results: PASSED
|
The gate is failing and it is not a false positive
Security GatereportsDEP_HIGH=20→Found 20 high severity dependency vulnerabilities - blocking merge.It was green on this exact commit (c0c803d) as recently as the 2026-09-13 scheduled run. Nothing in the repo changed; the advisory database did. The next scheduled run turns main red.
Reproduced locally against
origin/main's lockfile with the same scanner:20, matching the gate's count exactly.
Fix
@xmldom/xmldom— two branches, two independent patchesCVE-2026-83605 … -83619 (
requireWellformedbypasses viasetAttribute(), processing-instruction targets, etc.). The advisories patch each branch separately:>= 0.7.0, <= 0.8.14>= 0.9.0, <= 0.9.11The existing override was
"@xmldom/xmldom@<0.8.13": ">=0.8.13"— a floor that sits inside the vulnerable range, and both0.8.13and0.9.10were installed. Replaced with one ceiling per branch:The
<0.9.0ceiling on the first is deliberate: collapsing 0.8 consumers onto 0.9 is an API break, and it is not needed — 0.8.15 is patched.js-cookie—3.0.6→>=3.0.7(CVE-2026-46625)Verification
Lockfile regenerated with
pnpm install --lockfile-only(50 lines changed,lockfileVersionunchanged):@xmldom/xmldomjs-cookieRescanned the result:
20 → 0. No advisory was added to an ignore list, and no threshold was moved.
Not covered here
The same scan reports mediums/lows the gate does not block on (
qs,protobufjs,@tiptap/core,glib,mkdocs-material).@tiptap/corein particular needs 2.27.2 → 3.30.4, a major upgrade that does not belong in a gate-unblocking PR.