taintrace¶
Typosquat detector for AI coding agent dependencies.
taintrace scans your lockfiles for package names that suspiciously resemble
known legitimate packages — the vector used in the
arrayref@0.3.10 attack
(August 2026), where proc-macro1 imitated proc-macro2 and executed
arbitrary code during cargo build.
AI coding agents install dependencies automatically. Typosquats pass
cargo audit / npm audit unnoticed because they have no known CVE — they
are brand-new packages with a malicious build.rs or proc-macro. Those scanners
check known-bad. taintrace checks suspicious-similar.
I want to…¶
| I want to… | Do this |
|---|---|
| Scan one lockfile | taintrace check Cargo.lock |
| Scan every lockfile in a repo | taintrace scan-directory . |
| Gate a pipeline on typosquats | Use the exit code (1 = suspects) — see CI |
| Publish findings to Code Scanning | --format sarif — see CI |
| Consume results as JSON | --format json — see Usage |
| Check one package name | taintrace score proc-macro1 |
| Suppress a known false positive | --ignore / .taintrace.toml — see Configuration |
| Use it from Python | See the API Reference |
Install¶
Requires Python 3.10 or newer. No API keys, no network calls — the known-package database ships inside the package.
Sixty-second run¶
Given this Cargo.lock:
version = 3
[[package]]
name = "proc-macro1"
version = "0.3.10"
[[package]]
name = "serde"
version = "1.0.0"
╭──────────────────────────────────────────────────── Scan Results ────────────────────────────────────────────────────╮
│ taintrace v0.2.2 — scanning Cargo.lock │
│ Total deps: 2 | Suspects: 1 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
🚨 Typosquat Suspects
┏━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Package ┃ Risk ┃ Score ┃ Similar To ┃ Reason ┃
┡━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ proc-macro1 │ CRITICAL │ 1.00 │ proc-macro2 (1.00), parking_lot (1.00), │ Near-identical to 'proc-macro2' – likely │
│ │ │ │ tracing-log (0.75) │ typosquat │
└─────────────┴──────────┴───────┴──────────────────────────────────────────┴──────────────────────────────────────────┘
❌ 1 suspect(s) found — review required
Exit code 0 means clean, 1 means suspects were found.
Supported ecosystems¶
Nine ecosystems are covered. The ecosystem is detected from the lockfile
filename unless you pass --ecosystem:
| Ecosystem | Lockfiles |
|---|---|
| Rust | Cargo.lock, Cargo.toml |
| Node.js | package-lock.json, pnpm-lock.yaml, yarn.lock, bun.lock, bun.lockb |
| Python | requirements.txt, poetry.lock, pyproject.toml, uv.lock, Pipfile.lock |
| Go | go.sum |
| Ruby | Gemfile.lock |
| PHP | composer.json, composer.lock |
| Swift | Package.resolved, Package.swift |
| Elixir | mix.lock |
| Gradle | build.gradle, build.gradle.kts, gradle/libs.versions.toml |
Similarity suggestions come from a built-in, offline database: curated lists in
taintrace/db.py for Rust, Node.js, Python, Go, Ruby, PHP, Swift and Elixir,
plus 7,848 groupId:artifactId coordinates in
src/taintrace/data/java_packages.txt generated from the Maven Central index.
Where to go next¶
- Getting Started — install and first run
- Usage — every CLI flag
- Detection — how the score is actually computed
- Configuration — config discovery, keys, ignore lists
- CI — GitHub Action, pre-commit hook, SARIF upload
- Example typosquat reports
— runnable fixtures for
reqeusts,lodahsandraills
Links¶
- Source on GitHub
- Issues
- Changelog
- PyPI
- Contributing
- MIT licensed