Advisory cross-check + version resolution + recent-scan harness - #20
Closed
acuciureanu wants to merge 3 commits into
Closed
acuciureanu wants to merge 3 commits into
acuciureanu wants to merge 3 commits into
Conversation
The disclosure classifier decided "known-cve vs undocumented" from OSV.dev plus the built-in static DB only. OSV is not a complete mirror of the GitHub Advisory Database, so real npm prototype-pollution advisories are missing from it — e.g. deep-defaults (CVE-2021-25944 / GHSA-h6xg-rg33-9mf4) and deep-set (GHSA-wgxm-rg53-h2c6), both critical and both affecting their latest published version. With OSV as the only live source, the classifier labelled these "undocumented-vulnerability", i.e. manufactured false 0-day candidates. Add a second live source: the GitHub Advisory Database via the npm registry bulk endpoint (the source `npm audit` uses; no auth). Each advisory is adapted into the OSV vuln shape and merged into the same array the classifier already consumes, so classification logic is unchanged — a finding is "undocumented" only when the static DB, OSV, AND the GitHub Advisory DB all say unknown. Provenance is reported honestly (ghsa vs osv). --no-osv now governs both live sources. Fail-safe identical to osv.js: never throws, degrades gracefully. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CfAYfHFiDZmDVPuD3cy8W7
`--target foo@latest` (or a semver range / dist-tag) kept the literal spec as config.version all the way through the run. Every downstream consumer that keys on an exact version then misbehaved — most damagingly the OSV.dev and GitHub Advisory DB lookups, which query "latest" as if it were a version, match nothing, and let a KNOWN CVE be reported as an undocumented 0-day (observed on deep-defaults@latest → CVE-2021-25944 and deep-set@latest → CVE-2020-28276). After install, read the concrete version from node_modules/<pkg>/package.json and use it for discovery, the reported version, the PoC, and advisory lookups. With this, foo@latest resolves to e.g. 1.0.5 and both advisories match, so the findings correctly classify as known-cve. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CfAYfHFiDZmDVPuD3cy8W7
Add scripts/discovery/, a three-step pipeline for hunting undocumented
prototype-pollution gadgets in current npm libraries:
scan-recent.mjs discover PP-prone packages published since a cutoff (default
today, UTC) via the npm search endpoint + a package-name
relevance filter, ranked by weekly downloads.
sweep.sh fuzz each target in the hardened container, reusing
run-sandboxed.sh (cap-drop=ALL, seccomp, non-root, read-only
rootfs), advisory classification ON.
triage.mjs classify results; surface only reproduced *undocumented*
findings as disclosure candidates, exit 2 when any survive.
run-sandboxed.sh now allocates a TTY only when attached to one, so it works in
these batch loops and in CI.
.github/workflows/recent-scan.yml runs the pipeline daily (and on demand),
uploads the sweep artifact, and opens a tracking issue only when a candidate
survives. Informational; never gates other CI.
The tool is the finder, never the disclosure vehicle — see the README's
responsible-disclosure note.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfAYfHFiDZmDVPuD3cy8W7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Building a "scan the latest libraries for 0days" harness surfaced two real correctness bugs in the disclosure classifier — both of which made known CVEs masquerade as undocumented 0-day candidates. This PR fixes them and adds the harness.
Fixes (the important part)
fix(target): resolve dist-tag/range specs to the installed version.--target foo@latestkept the literal"latest"asconfig.version, so OSV/GitHub-Advisory-DB lookups queried"latest"(matching nothing) and any reproduced pollution was labelled undocumented. Now the concrete installed version (fromnode_modules/<pkg>/package.json) is used for discovery, the PoC, the reported version, and advisory lookups.fix(disclosure): cross-check the GitHub Advisory DB, not OSV alone. Adds the npm bulk advisory endpoint as a second live source (adapted to the OSV vuln shape and merged, so the classifier is unchanged). A finding is undocumented only when the static DB, OSV, and the GitHub Advisory DB all have nothing. Provenance (ghsavsosv) is reported honestly;--no-osvgoverns both.Validation:
deep-defaults@latestanddeep-set@latest— previously false "undocumented" candidates — now correctly classify asknown-cve(CVE-2021-25944, CVE-2020-28276), reproduced 2× in the hardened container.Feature
feat(discovery):scripts/discovery/—scan-recent.mjs(discover PP-prone packages published since a cutoff) →sweep.sh(fuzz each in the sandbox, reusingrun-sandboxed.sh) →triage.mjs(surface only reproduced undocumented findings). Plus.github/workflows/recent-scan.yml(daily + on-demand, informational, opens an issue only on a surviving candidate).run-sandboxed.shis now TTY-aware so it works in loops/CI.The tool is the finder, never the disclosure vehicle — see
scripts/discovery/README.md.Tests
319 tests, 317 pass / 0 fail (2 pre-existing skips); lint clean. New coverage for the npm-advisory source/adapter and the installed-version resolver.
🤖 Generated with Claude Code