Metadata-Version: 2.4
Name: taintrace
Version: 0.2.0
Summary: Typosquat detector for AI coding agent dependencies
Author-email: Yunare Maia <yunare@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/yunaremaia/taintrace
Project-URL: Issues, https://github.com/yunaremaia/taintrace/issues
Project-URL: Funding, https://github.com/sponsors/yunaremaia
Keywords: security,supply-chain,typosquat,ai-agents,dependencies
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1
Requires-Dist: rich>=13.0
Requires-Dist: rapidfuzz>=3.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Dynamic: license-file

# 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](https://github.com/rustsec/advisory-db/pull/2045) (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

```bash
pip install taintrace
```

## Usage

### Scan a lockfile

```bash
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)

```bash
taintrace check Cargo.lock --format json
```

### SARIF output (GitHub Code Scanning)

```bash
taintrace check Cargo.lock --format sarif > results.sarif
```

### Score a single package

```bash
taintrace score proc-macro1
```

### Exit codes

- `0` — no suspects found
- `1` — 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

```yaml
- 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:

```yaml
- uses: yunaremaia/taintrace@main
  with:
    format: cli
```

### Pre-commit hook

```yaml
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](LICENSE)
