feat(enrichment): typosquat & dependency-confusion analyzer#1704
Conversation
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review — safe to merge
✅ Approved — safe to merge Review summary
Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
Review detailsGenerated from public PR metadata and the diff. Advisory only; deterministic signals remain authoritative. The change adds a new enrichment analyzer for newly added dependency names, wires it into the analyzer registry, extends the structured finding type, and renders the resulting typosquat/confusion findings. The implementation is mostly coherent and fail-safe: scoped packages are explicitly excluded before near-miss and registry checks, registry uncertainty returns no finding, and the new tests cover the main pure and scan paths. The notable rough edge is documentation/test coverage around limits and stale wording, not a must-fix correctness break in the shown code. Nits (5)
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
fa10480 to
8f9ef67
Compare
dcce39a to
c5ea5d7
Compare
Add a REES analyzer that flags two supply-chain risks for the dependencies a PR newly adds, which the no-checkout in-prompt reviewer cannot detect: - Typosquat: an UNSCOPED name that is a near-miss of a bundled popular package — a homoglyph/separator variant (canonical-form match) or a distance-1 Damerau-Levenshtein edit (with a short-name guard). Scoped names (@scope/x) are namespace-protected and never classified, so a popular tail under any scope (@types/react, @acme/express) is not a false positive. Pure, offline. - Dependency-confusion: an unscoped name that returns a definitive 404 on the public registry is publicly claimable. Uses an injected fetch; transient/unknown states fail safe (no finding). A known-legitimate near-neighbour allowlist (e.g. preact vs react) is exempt from name flagging. Reuses extractDependencyChanges to read added (not bumped) deps from the diff. Registered in the brief orchestrator and rendered as a public-safe block (package@version + reason only). Tests live in their own file to avoid colliding with concurrent analyzer work on enrichment.test.ts. Closes JSONbored#1501
c5ea5d7 to
83fd64c
Compare
Summary
Adds a REES analyzer (#1501) that flags two supply-chain risks for the dependencies a PR newly adds — the heavy/external name analysis the no-checkout
claude --printreviewer cannot do. Additive + fail-safe: it fills its owntyposquatfindings key and degrades independently like every other analyzer.Detects (unscoped names only)
l0dash,lo-dash→lodash),expres→express), with a short-name guard and a known-legitimate near-neighbour allowlist (e.g.preactis not flagged as a near-miss ofreact). Pure + offline.Scope note — scoped packages are intentionally not analyzed. An npm scope is namespace-protected (it cannot be published to without owning it), so a popular tail under any scope —
@types/react,@chakra-ui/react,@acme/express— is not claimable impersonation. There is no offline source of truth that distinguishes a legitimate scoped package from a hypothetical malicious one, so classifying scoped names would only manufacture false positives. The analyzer therefore restricts to the unscoped flat namespace, which is the real typosquat/confusion surface. (This deliberately narrows the issue's "scope-swap" idea to keep the analyzer precise.)Implementation (established
review-enrichment/pattern)TyposquatFindingtype +typosquat?key insrc/types.tssrc/analyzers/typosquat.ts— pure helpers (damerauLevenshtein,canonicalize,classifyTyposquat,isPublished) +scanTyposquat(req, fetch, opts); reusesextractDependencyChangesto read added (not bumped) depssrc/brief.tsANALYZERS registrysrc/render.ts(renderspackage@version+ reason only — never manifest contents)node:testunits in a separatetest/typosquat.test.ts(avoids colliding with concurrent analyzer PRs onenrichment.test.ts)Validation
From
review-enrichment/(Node 24):Covers edit-distance/transposition/bounded early-exit, homoglyph + separator canonicalization, short-name guard, known-legit exemption, scoped-name non-classification (incl.
@chakra-ui/react), registry 404/200/5xx/throw/abort, version-bump-ignored, scoped-name skipped, fail-safe, and the rendered public-safe block.Closes #1501