| name | detecting-typosquatting-packages-in-npm-pypi |
| description | Detects typosquatting attacks in npm and PyPI package registries by analyzing package name similarity using Levenshtein distance and other string metrics, examining publish date heuristics to identify recently created packages mimicking established ones, and flagging download count anomalies where suspicious packages have disproportionately low usage compared to their legitimate targets. The analyst queries the PyPI JSON API and npm registry API to gather package metadata for automated comparison. Activates for requests involving package typosquatting detection, dependency confusion analysis, malicious package identification, or software supply chain threat hunting in package registries.
|
| domain | cybersecurity |
| subdomain | supply-chain-security |
| tags | ["typosquatting","npm","pypi","supply-chain","package-security","Levenshtein","dependency-confusion","malicious-packages"] |
| version | 1.0.0 |
| author | mukul975 |
| license | Apache-2.0 |
| nist_csf | ["GV.SC-01","GV.SC-03","GV.SC-06","GV.SC-07"] |
Detecting Typosquatting Packages in npm and PyPI
When to Use
- Auditing project dependencies to identify packages whose names are suspiciously similar to popular libraries
- Proactively scanning package registries for newly published packages that may be typosquats of your organization's packages
- Investigating a suspected supply chain compromise where a developer installed a misspelled package name
- Building automated monitoring that alerts when new packages appear with names close to critical dependencies
- Assessing the risk profile of unfamiliar packages before adding them to a project's dependency tree
Do not use as the sole determination of malicious intent; name similarity alone does not prove a package is malicious. Do not use for bulk automated takedown requests without manual review of flagged packages. Do not use against private registries without authorization.
Detection Gaps & Validation
Pure Levenshtein matching catches the obvious misspellings and misses the attack classes that look nothing like a typo at the byte level.
- Homoglyph / Unicode confusables: Cyrillic
а (U+0430) vs Latin a, or rn vs m, have Levenshtein distance 0 after a naive lowercase compare yet are visually identical. Normalize via Unicode confusable mapping (unicodedata / confusable_homoglyphs) before scoring.
- Combosquatting: prefix/suffix additions (
python-requests, requests-aws, requests2) can sit at edit distance 5+ from the target and slip past a distance-2 threshold. Match on token containment, not just edit distance.
- Scope / namespace confusion (npm):
@myorg/utils vs an unscoped public utils, or a look-alike scope @my-org/utils, is a different attack than character mutation. Normalize and compare scope separately.
- PEP 503 normalization gaps: failing to fold
-, _, . (my-pkg ↔ my_pkg ↔ my.pkg) before comparison causes missed matches on PyPI.
How to validate: seed your watchlist with a few known historical typosquats (e.g. python3-dateutil, jeIlyfish/jellyfish, ) and confirm the detector flags them HIGH; then confirm a legitimate similar pair ( vs ) is auto-blocked but routed to manual review. Pair every name-distance hit with a metadata signal — different author, first upload < 90 days, download ratio < 0.001 — before classifying. Name similarity alone is a lead, not a verdict.