Repository navigation
fix(supply-chain): relative edit distance for SC6 typosquat detection - #104
Conversation
…etection Absolute edit-distance <= 2 produces false positives on short, legitimate package names: "task" is a real package and is edit-distance 2 from "flask", yet was flagged as a possible typosquat (one of the cases reported in NVIDIA#103). Add a relative-distance guard (dist/shorter_len <= 1/3) so short names need an all-but-one-character match while longer names may still differ by two characters. Existing behaviour is preserved: - "reqeusts" -> "requests" (len 8, dist 2) still flagged - "expreess" -> "express" (dist 1) still flagged - "task" -> "flask" (len 4, dist 2) no longer flagged Adds a regression test; all existing SC4/SC5/SC6 unit tests still pass and ruff is clean. Refs NVIDIA#103 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: Yonatan Gross <[email protected]>
rng1995
left a comment
There was a problem hiding this comment.
Sensible improvement to cut typosquat false positives. Approving.
The relative-distance guard (dist * 3 > shorter -> continue, i.e. require edit-distance ≤ ⅓ of the shorter name) correctly distinguishes real short packages from typosquats: task vs flask (distance 2 on a 4-char name) is no longer flagged, while reqeusts vs requests (distance 2 on 8 chars) still is. The comment explaining the rationale is appreciated, and the regression test pins both cases.
Minor / optional (non-blocking): this does reduce recall for short popular names — a 2-edit squat against a ≤5-char target (e.g. a 5-char package) won't trip the absolute-≤2 path anymore, only 1-edit squats will. That's a reasonable precision/recall tradeoff and is well documented, just flagging it for awareness.
What
Fixes one of the false positives reported in #103: SC6 typosquat detection
uses an absolute edit-distance threshold of 2, which collides on short,
legitimate package names.
taskis a real package and is edit-distance 2from
flask, so it was flagged as a "possible typosquat".Fix
Add a relative-distance guard to
_is_typosquat: a genuine typosquat perturbsonly a small fraction of the name, so require
dist / shorter_len <= 1/3.Short names then need an all-but-one-character match, while longer names may
still differ by two characters.
reqeusts→requestsexpreess→expresstask→flaskTest plan
test_is_typosquat_short_distinct_name_not_flagged)asserting
task/flaskis not flagged whilereqeusts/requestsstill is.pytest tests/unit/test_patterns_new.py— 177 passed (all existingSC4/SC5/SC6 assertions preserved).
package.jsonwithtask+expreessdeps nowreports SC6 for
expreessonly.ruff check src/ tests/clean.Signed off per DCO. Refs #103.