taintrace
Typosquat detector for AI coding agent dependencies.
taintrace scans your lockfiles (Cargo.lock, package-lock.json, requirements.txt, go.sum) for package names that suspiciously resemble known legitimate packages — the exact vector used in the arrayref@0.3.10 attack (August 2026), where proc-macro1 imitated proc-macro2 to execute arbitrary code during cargo build.
The Problem
AI coding agents install dependencies automatically. Typosquats pass undetected by scanners like cargo audit or npm audit because they have no known CVE — they're brand new packages with malicious build.rs or proc-macros.
Traditional scanners check known-bad. taintrace checks suspicious-similar.
Install
pip install taintrace
Usage
Scan a lockfile
taintrace check Cargo.lock
╭──────────────────────────────────────────────╮
│ taintrace v0.1.0 — scanning Cargo.lock │
│ Total deps: 42 | Suspects: 1 │
╰──────────────────────────────────────────────╯
🚨 Typosquat Suspects
┏━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Package ┃ Risk ┃ Score ┃ Similar To ┃ Reason ┃
┣━━━━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━╋━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ proc-macro1 ┃ CRITICAL ┃ 0.980 ┃ proc-macro2 ┃ Near-identical to... ┃
┗━━━━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━┛
❌ 1 suspect(s) found — review required
JSON output (CI/CD)
taintrace check Cargo.lock --format json
SARIF output (GitHub Code Scanning)
taintrace check Cargo.lock --format sarif > results.sarif
Score a single package
taintrace score proc-macro1
Exit codes
0— no suspects found1— one or more suspects detected (use in CI/CD gates)
Algorithms
- Levenshtein distance — edit distance between names
- Soundex phonetic — catches homophones ("night" vs "nite")
- Substring matching — detects containment ("lodash" vs "lodash1")
- Combined scoring — weighted combination of all signals
Multi-ecosystem
| Ecosystem | Lockfile | Status |
|---|---|---|
| Rust | Cargo.lock | ✅ |
| Node.js | package-lock.json | ✅ |
| Python | requirements.txt | ✅ |
| Go | go.sum | ✅ |
Multi-ecosystem
| Ecosystem | Lockfiles | Status |
|---|---|---|
| Rust | Cargo.lock, Cargo.toml | ✅ |
| Node.js | package-lock.json, pnpm-lock.yaml, yarn.lock | ✅ |
| Python | requirements.txt, poetry.lock | ✅ |
| Go | go.sum | ✅ |
CI/CD integration
GitHub Action
- uses: yunaremaia/taintrace@main
with:
lockfile: Cargo.lock
format: sarif
sarif-output: taintrace.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: taintrace.sarif
Auto-detect lockfiles in your repo root:
- uses: yunaremaia/taintrace@main
with:
format: cli
Pre-commit hook
repos:
- repo: https://github.com/yunaremaia/taintrace
rev: v0.2.0
hooks:
- id: taintrace
Why taintrace?
- AI-agent-aware — built for the vector AI agents expose (automatic dep installation)
- Zero config — just point at your lockfile
- Offline-first — no API calls, no data leaves your machine
- SARIF-native — integrates with GitHub Code Scanning
- Open source — MIT licensed, no paywall
How it differs
| Tool | CVE-based | Typosquat | AI-aware | Open source |
|---|---|---|---|---|
| cargo-audit | ✅ | ❌ | ❌ | ✅ |
| npm audit | ✅ | ❌ | ❌ | ✅ |
| Socket | ✅ | Partial | ❌ | ❌ |
| Phylum | ✅ | Partial | ❌ | ❌ |
| taintrace | ❌ | ✅ | ✅ | ✅ |
License
MIT — see LICENSE
Metadata
Release files for taintrace 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| taintrace-0.2.0.tar.gz | 17.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| taintrace-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.4 kB
Release files / taintrace-0.2.0.tar.gz
| Download URL | taintrace-0.2.0.tar.gz |
|---|---|
| Size | 17.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8877174395518e1afdccdd5d983cd73de2871723697a0d5d2a3a5a61d9198794
|
|
BLAKE2b-256 checksum How to use checksums |
5af187a04d6115146a035c40601e6bb96dfe5dbd187f51a65107a97f744c4d41
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency logRelease files / taintrace-0.2.0-py3-none-any.whl
| Download URL | taintrace-0.2.0-py3-none-any.whl |
|---|---|
| Size | 14.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2776630eb941b0e53473fbbdbca5d1dda3aa5fa44ee435993891de8bd989aa98
|
|
BLAKE2b-256 checksum How to use checksums |
735e5f33effd5337195d894e547f1d5ff19d2cebe56d5df17cb4b867bc5204fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency log