security-autopilot 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- security_autopilot-0.1.0/.claude/settings.local.json +25 -0
- security_autopilot-0.1.0/.github/workflows/ci.yml +27 -0
- security_autopilot-0.1.0/.gitignore +5 -0
- security_autopilot-0.1.0/CLAUDE.md +150 -0
- security_autopilot-0.1.0/PKG-INFO +235 -0
- security_autopilot-0.1.0/README.md +219 -0
- security_autopilot-0.1.0/daemon/__init__.py +0 -0
- security_autopilot-0.1.0/daemon/launchd.plist.template +34 -0
- security_autopilot-0.1.0/daemon/main.py +187 -0
- security_autopilot-0.1.0/daemon/scheduler.py +90 -0
- security_autopilot-0.1.0/daemon/systemd.service.template +16 -0
- security_autopilot-0.1.0/daemon/watcher.py +122 -0
- security_autopilot-0.1.0/docs/index.html +145 -0
- security_autopilot-0.1.0/install.sh +174 -0
- security_autopilot-0.1.0/mcp_server/__init__.py +0 -0
- security_autopilot-0.1.0/mcp_server/__main__.py +5 -0
- security_autopilot-0.1.0/mcp_server/aggregator.py +122 -0
- security_autopilot-0.1.0/mcp_server/server.py +195 -0
- security_autopilot-0.1.0/mcp_server/telemetry.py +98 -0
- security_autopilot-0.1.0/mcp_server/tools/__init__.py +0 -0
- security_autopilot-0.1.0/mcp_server/tools/gitleaks.py +94 -0
- security_autopilot-0.1.0/mcp_server/tools/installer.py +131 -0
- security_autopilot-0.1.0/mcp_server/tools/scan_repo.py +135 -0
- security_autopilot-0.1.0/mcp_server/tools/semgrep.py +85 -0
- security_autopilot-0.1.0/mcp_server/tools/supply_chain.py +356 -0
- security_autopilot-0.1.0/mcp_server/tools/trivy.py +86 -0
- security_autopilot-0.1.0/pyproject.toml +40 -0
- security_autopilot-0.1.0/schemas/finding.json +17 -0
- security_autopilot-0.1.0/tests/__init__.py +0 -0
- security_autopilot-0.1.0/tests/fixtures/axios_attack/package.json +18 -0
- security_autopilot-0.1.0/tests/test_integration.py +124 -0
- security_autopilot-0.1.0/tests/test_supply_chain.py +79 -0
- security_autopilot-0.1.0/uv.lock +811 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(gh repo:*)",
|
|
5
|
+
"Bash(open:*)",
|
|
6
|
+
"Bash(git add:*)",
|
|
7
|
+
"Bash(git commit -m ':*)",
|
|
8
|
+
"Bash(git push:*)",
|
|
9
|
+
"Bash(bash -n install.sh)",
|
|
10
|
+
"Bash(chmod +x install.sh)",
|
|
11
|
+
"Bash(gh pr:*)",
|
|
12
|
+
"Bash(git checkout:*)",
|
|
13
|
+
"Bash(git cherry-pick:*)",
|
|
14
|
+
"Bash(git pull:*)",
|
|
15
|
+
"Bash(uv run:*)",
|
|
16
|
+
"Bash(bash -n /Users/dahleh/Desktop/projects/security-autopilot/install.sh)",
|
|
17
|
+
"Bash(gh api:*)",
|
|
18
|
+
"Bash(git rm:*)",
|
|
19
|
+
"Bash(xargs -I{} gh api --method PATCH repos/Omar-Dahleh/security-autopilot/dependabot/alerts/{} -f state=dismissed -f dismissed_reason=tolerable_risk -f dismissed_comment=\"Demo files removed from repo\")",
|
|
20
|
+
"Bash(curl -s https://pypi.org/pypi/security-autopilot/json)",
|
|
21
|
+
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\('TAKEN — version', d['info']['version']\\)\")",
|
|
22
|
+
"Bash(uv build:*)"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Install uv
|
|
16
|
+
uses: astral-sh/setup-uv@v3
|
|
17
|
+
with:
|
|
18
|
+
version: "latest"
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
run: uv python install 3.11
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv sync --all-extras
|
|
25
|
+
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: uv run pytest tests/ -v
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Security Autopilot
|
|
2
|
+
|
|
3
|
+
MCP server that gives Claude Code native security scanning by wrapping four
|
|
4
|
+
tools — Trivy, Gitleaks, Semgrep, and a custom supply chain checker — and
|
|
5
|
+
exposing them as MCP tools. Users install via a one-liner (`install.sh`);
|
|
6
|
+
Claude Code then calls `scan_repo`, `scan_file`, `get_findings`, or
|
|
7
|
+
`watch_project` directly from the chat prompt.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv run pytest tests/ -v # run all tests
|
|
15
|
+
python -m mcp_server.server # start MCP server (stdio)
|
|
16
|
+
uv tool install security-autopilot # install as CLI tool
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## File map (every file, one line)
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
install.sh one-liner installer hosted at get.securityautopilot.dev
|
|
25
|
+
docs/index.html minimal dark landing page (pure HTML, no framework)
|
|
26
|
+
schemas/finding.json JSON Schema for a single finding — all scanners must conform
|
|
27
|
+
pyproject.toml package config; entry point: mcp_server.server:main
|
|
28
|
+
|
|
29
|
+
mcp_server/server.py MCP tool definitions + dispatch; calls telemetry on startup
|
|
30
|
+
mcp_server/aggregator.py SQLite cache at ~/.security-autopilot/findings.db
|
|
31
|
+
mcp_server/telemetry.py opt-in anonymous usage pings via PostHog HTTP API (stdlib only)
|
|
32
|
+
mcp_server/__main__.py allows `python -m mcp_server.server`
|
|
33
|
+
|
|
34
|
+
mcp_server/tools/scan_repo.py orchestrates all 4 scanners in parallel via asyncio.gather
|
|
35
|
+
mcp_server/tools/supply_chain.py core scanner: KNOWN_BAD list, lifecycle scripts, maintainer hijacks
|
|
36
|
+
mcp_server/tools/trivy.py CVE scanner — shells out to trivy CLI
|
|
37
|
+
mcp_server/tools/gitleaks.py secret detection — shells out to gitleaks CLI
|
|
38
|
+
mcp_server/tools/semgrep.py SAST — shells out to semgrep CLI
|
|
39
|
+
mcp_server/tools/installer.py auto-installs trivy/gitleaks/semgrep if missing (macOS + Linux)
|
|
40
|
+
|
|
41
|
+
daemon/watcher.py watchdog daemon; re-scans on manifest file changes; sends desktop notifications
|
|
42
|
+
daemon/scheduler.py auto-detects new projects in ~/projects, ~/code, ~/Desktop/projects
|
|
43
|
+
|
|
44
|
+
tests/test_supply_chain.py unit tests for supply chain scanner (axios attack fixture)
|
|
45
|
+
tests/test_integration.py integration tests for scan_repo end-to-end
|
|
46
|
+
tests/fixtures/axios_attack/ package.json pinned to axios@1.14.1 (known-bad)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Unified finding schema
|
|
52
|
+
|
|
53
|
+
Every scanner must return a `list[dict]` where each dict conforms to
|
|
54
|
+
`schemas/finding.json`. Deviations will fail aggregator validation.
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
59
|
+
"title": "SecurityFinding",
|
|
60
|
+
"type": "object",
|
|
61
|
+
"required": ["id", "scanner", "severity", "title", "description", "remediation"],
|
|
62
|
+
"properties": {
|
|
63
|
+
"id": { "type": "string", "format": "uuid" },
|
|
64
|
+
"scanner": { "type": "string", "enum": ["supply_chain", "trivy", "gitleaks", "semgrep"] },
|
|
65
|
+
"severity": { "type": "string", "enum": ["critical", "high", "medium", "low", "info"] },
|
|
66
|
+
"title": { "type": "string" },
|
|
67
|
+
"description": { "type": "string" },
|
|
68
|
+
"file": { "type": ["string", "null"] },
|
|
69
|
+
"line": { "type": ["integer", "null"] },
|
|
70
|
+
"remediation": { "type": "string" },
|
|
71
|
+
"references": { "type": "array", "items": { "type": "string" } }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Severity values:** `critical | high | medium | low | info`
|
|
77
|
+
**Rule:** if the CLI tool is not installed, return one `info` finding —
|
|
78
|
+
never raise an exception.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Known-bad versions list
|
|
83
|
+
|
|
84
|
+
`mcp_server/tools/supply_chain.py` → `KNOWN_BAD` list at the top of the file.
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
KNOWN_BAD: list[dict[str, str]] = [
|
|
88
|
+
{"name": "axios", "version": "1.14.1", "reason": "supply chain RAT March 2026 — postinstall dropper"},
|
|
89
|
+
{"name": "axios", "version": "0.30.4", "reason": "supply chain RAT March 2026 — postinstall dropper"},
|
|
90
|
+
{"name": "plain-crypto-js", "version": "4.2.1", "reason": "axios attack dropper — remote access trojan"},
|
|
91
|
+
]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Add new entries as `{"name": "pkg", "version": "x.y.z", "reason": "..."}`.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Adding a new scanner
|
|
99
|
+
|
|
100
|
+
1. Create `mcp_server/tools/my_scanner.py`
|
|
101
|
+
2. Implement `async def scan(project_path: str) -> list[dict]`
|
|
102
|
+
3. Each finding must conform to the schema above
|
|
103
|
+
4. Return an `info` finding (not a crash) if the CLI tool is not installed
|
|
104
|
+
5. Add to `_SCANNER_MAP` in `scan_repo.py`
|
|
105
|
+
6. Register the new scanner name in `schemas/finding.json` → `scanner.enum`
|
|
106
|
+
7. Add tests in `tests/`
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Coding rules
|
|
111
|
+
|
|
112
|
+
- **Async only** — all scanner functions are `async def`; no blocking I/O on
|
|
113
|
+
the event loop. Shell out with `asyncio.create_subprocess_exec`, not
|
|
114
|
+
`subprocess.run`.
|
|
115
|
+
- **Graceful degradation** — a missing CLI tool, network timeout, or parse
|
|
116
|
+
error must never crash the server. Return an `info` finding with a clear
|
|
117
|
+
message; log the exception to stderr.
|
|
118
|
+
- **Idempotency** — `install.sh` and the claude.json patch are safe to run
|
|
119
|
+
multiple times without side effects.
|
|
120
|
+
- **No new dependencies for telemetry** — `telemetry.py` uses stdlib `urllib`
|
|
121
|
+
only. Do not add the PostHog SDK.
|
|
122
|
+
- **Test coverage** — every scanner needs at minimum: (a) a happy-path test
|
|
123
|
+
with a real fixture, (b) a test for the "tool not installed" info-finding
|
|
124
|
+
path. Integration tests live in `test_integration.py`.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Current status
|
|
129
|
+
|
|
130
|
+
### Built
|
|
131
|
+
- MCP server with four tools: `scan_repo`, `scan_file`, `get_findings`, `watch_project`
|
|
132
|
+
- Supply chain scanner with KNOWN_BAD blocklist, lifecycle script detection, maintainer hijack heuristics
|
|
133
|
+
- Trivy, Gitleaks, Semgrep wrappers that shell out to CLI tools
|
|
134
|
+
- Auto-installer (`installer.py`) for missing CLI tools — macOS (brew) + Linux (curl)
|
|
135
|
+
- SQLite findings cache via `aggregator.py`
|
|
136
|
+
- Background file watcher (`daemon/watcher.py`) + project auto-detector (`daemon/scheduler.py`)
|
|
137
|
+
- Opt-in anonymous telemetry (`telemetry.py`) — PostHog, no SDK, prompted on first run
|
|
138
|
+
- `install.sh` one-liner for end users
|
|
139
|
+
- `docs/index.html` minimal landing page
|
|
140
|
+
|
|
141
|
+
### PostHog key not yet configured
|
|
142
|
+
`mcp_server/telemetry.py` line 17 and `docs/index.html` line 9 both contain
|
|
143
|
+
`YOUR_POSTHOG_KEY` — replace with the real `phc_...` key once the account is created.
|
|
144
|
+
|
|
145
|
+
### What's next (known gaps)
|
|
146
|
+
- No CLI beyond the MCP server — `security-autopilot daemon start` does not exist
|
|
147
|
+
- `daemon/scheduler.py` has no entry point wired to `server.py`
|
|
148
|
+
- No PyPI publish yet (`uv tool install security-autopilot` will fail until published)
|
|
149
|
+
- GitHub Actions CI (`ci.yml`) — verify it passes on push
|
|
150
|
+
- `install.sh` tested locally but not yet on a clean Ubuntu 22 VM
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: security-autopilot
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server giving Claude Code native security scanning superpowers
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Requires-Dist: aiosqlite>=0.20.0
|
|
8
|
+
Requires-Dist: httpx>=0.27.0
|
|
9
|
+
Requires-Dist: mcp>=1.0.0
|
|
10
|
+
Requires-Dist: pydantic>=2.0.0
|
|
11
|
+
Requires-Dist: watchdog>=4.0.0
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
14
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
<div align="center">
|
|
18
|
+
|
|
19
|
+
# 🛡️ Security Autopilot
|
|
20
|
+
|
|
21
|
+
### The security scanner that works *while you code* — not after you ship.
|
|
22
|
+
|
|
23
|
+
[](tests/)
|
|
24
|
+
[](pyproject.toml)
|
|
25
|
+
[](LICENSE)
|
|
26
|
+
[](https://modelcontextprotocol.io)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## The Problem
|
|
33
|
+
|
|
34
|
+
On **March 30, 2026**, two malicious versions of `axios` — one of the most downloaded npm packages on the planet — were quietly published to npm.
|
|
35
|
+
|
|
36
|
+
They contained **zero suspicious code inside axios itself**. Any developer who inspected the source would have found nothing wrong.
|
|
37
|
+
|
|
38
|
+
Instead, they silently injected a fake dependency called `plain-crypto-js` that ran a **postinstall script the moment you ran `npm install`**. That script phoned home to a command-and-control server and dropped a remote access trojan tailored to your OS.
|
|
39
|
+
|
|
40
|
+
After delivering the payload, it deleted itself and swapped its own `package.json` for a clean decoy. **No trace. No warning. No audit trail.**
|
|
41
|
+
|
|
42
|
+
`npm audit` reported nothing. GitHub Dependabot reported nothing. Standard code review caught nothing.
|
|
43
|
+
|
|
44
|
+
> **This is the new shape of supply chain attacks** — and your existing tools aren't built to catch them.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## What Security Autopilot Does
|
|
49
|
+
|
|
50
|
+
Security Autopilot is an **MCP server** that plugs directly into Claude Code and gives it real security scanning superpowers. You talk to Claude naturally — it runs the scans.
|
|
51
|
+
|
|
52
|
+
It catches the class of attacks that traditional tools miss:
|
|
53
|
+
|
|
54
|
+
| What it catches | How it catches it |
|
|
55
|
+
|---|---|
|
|
56
|
+
| 🔴 **Known-malicious packages** (axios@1.14.1, plain-crypto-js@4.2.1) | Blocklist checked before any install |
|
|
57
|
+
| 🟠 **Maintainer account hijacks** | Detects publisher email changes between versions |
|
|
58
|
+
| 🟠 **Postinstall script injection** | Flags any `preinstall`, `install`, `postinstall`, `prepare` lifecycle scripts |
|
|
59
|
+
| 🟡 **Recently published versions** | 72-hour cooldown gate on new releases |
|
|
60
|
+
| 🔵 **Floating version pins** | Flags `^` and `~` pins that allow silent upgrades |
|
|
61
|
+
| 🔵 **Missing SLSA provenance** | Detects packages published without cryptographic build attestations |
|
|
62
|
+
| 🟠 **Exposed secrets & credentials** | Gitleaks scans every file for hardcoded API keys, tokens, passwords |
|
|
63
|
+
| 🟡 **CVEs in your dependencies** | Trivy scans against the full NVD vulnerability database |
|
|
64
|
+
| 🟡 **Code-level security bugs** | Semgrep catches `eval(userInput)`, SQL injection, XSS, and 1000+ other patterns |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## How It Works
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
You type: "is my supply chain safe?"
|
|
72
|
+
│
|
|
73
|
+
▼
|
|
74
|
+
Claude Code calls scan_repo()
|
|
75
|
+
│
|
|
76
|
+
┌─────────┴──────────┐
|
|
77
|
+
│ 4 scanners run │ ← all in parallel, ~10 seconds total
|
|
78
|
+
│ simultaneously │
|
|
79
|
+
└─────────┬──────────┘
|
|
80
|
+
│
|
|
81
|
+
┌─────────┴────────────────────────────────────┐
|
|
82
|
+
│ Supply Chain │ Trivy │ Gitleaks │ Semgrep │
|
|
83
|
+
└─────────┬────────────────────────────────────┘
|
|
84
|
+
│
|
|
85
|
+
▼
|
|
86
|
+
Claude summarises findings in plain English
|
|
87
|
+
with severity, location, and exact fix steps
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Missing a scanner? **Security Autopilot installs it for you automatically** — no setup required.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Quick Start
|
|
95
|
+
|
|
96
|
+
### 1. Install (one command)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
curl -fsSL https://get.securityautopilot.dev | sh
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This installs `uv`, the MCP server, all scanner CLIs (trivy, gitleaks, semgrep), and automatically patches `~/.claude/claude.json` to register the plugin. Safe to run twice.
|
|
103
|
+
|
|
104
|
+
> **Telemetry:** On first run you'll be asked whether to share anonymous usage data (OS + Python version). You can opt out at any time by deleting `~/.security-autopilot/telemetry_consent`.
|
|
105
|
+
|
|
106
|
+
### 2. Restart Claude Code
|
|
107
|
+
|
|
108
|
+
That's it — no manual config needed.
|
|
109
|
+
|
|
110
|
+
### 3. Just talk to Claude
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
"scan this project for security issues"
|
|
114
|
+
"any secrets exposed in this codebase?"
|
|
115
|
+
"is my supply chain safe?"
|
|
116
|
+
"check my dependencies for known vulnerabilities"
|
|
117
|
+
"watch this project and alert me to new issues"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## What a Scan Looks Like
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
## Security Scan: `/your/project`
|
|
126
|
+
Scanners: supply_chain, trivy, gitleaks, semgrep | Duration: 8.3s
|
|
127
|
+
Found: 4 issues — 🔴 1 critical 🟠 2 high 🟡 0 medium 🔵 1 low
|
|
128
|
+
|
|
129
|
+
### 🔴 [CRITICAL] Known-malicious package: axios@1.14.1
|
|
130
|
+
Location: package.json
|
|
131
|
+
Scanner: supply_chain
|
|
132
|
+
|
|
133
|
+
axios@1.14.1 is on the known-bad blocklist.
|
|
134
|
+
Reason: supply chain RAT March 2026 — postinstall dropper
|
|
135
|
+
|
|
136
|
+
Remediation: Remove axios@1.14.1 immediately. Downgrade to axios@1.14.0.
|
|
137
|
+
Rotate all secrets on affected machines — this version installs a
|
|
138
|
+
remote access trojan.
|
|
139
|
+
|
|
140
|
+
### 🟠 [HIGH] Exposed aws-secret-access-key secret in .env
|
|
141
|
+
Location: .env:3
|
|
142
|
+
Scanner: gitleaks
|
|
143
|
+
|
|
144
|
+
Rotate this credential immediately — assume it is compromised.
|
|
145
|
+
Add `.env` to .gitignore to prevent future commits.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## MCP Tools
|
|
151
|
+
|
|
152
|
+
Claude gets access to 4 tools automatically:
|
|
153
|
+
|
|
154
|
+
| Tool | What it does |
|
|
155
|
+
|---|---|
|
|
156
|
+
| `scan_repo(path)` | Full scan — all 4 scanners in parallel |
|
|
157
|
+
| `scan_file(filepath)` | Scan a single file |
|
|
158
|
+
| `get_findings(severity)` | Retrieve cached findings from previous scans |
|
|
159
|
+
| `watch_project(path)` | Start a background daemon that re-scans on file changes |
|
|
160
|
+
|
|
161
|
+
The background watcher also sends a **desktop notification** the moment a new critical or high finding is detected — even if Claude Code isn't open.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Scanners
|
|
166
|
+
|
|
167
|
+
| Scanner | What it catches | Auto-installed? |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| **Supply Chain** | Known-bad versions, account hijacks, lifecycle scripts, floating pins, SLSA gaps | ✅ Built-in |
|
|
170
|
+
| **Trivy** | CVEs in npm, pip, Go, Rust, Java dependencies | ✅ Auto-installed |
|
|
171
|
+
| **Gitleaks** | Hardcoded secrets, API keys, tokens, passwords | ✅ Auto-installed |
|
|
172
|
+
| **Semgrep** | 1000+ SAST rules: injection, XSS, insecure patterns | ✅ Auto-installed |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## For Contributors
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Run tests
|
|
180
|
+
uv run pytest tests/ -v
|
|
181
|
+
|
|
182
|
+
# Start the MCP server manually
|
|
183
|
+
python -m mcp_server.server
|
|
184
|
+
|
|
185
|
+
# Add a new scanner
|
|
186
|
+
# → see CLAUDE.md for the exact pattern to follow
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Adding a scanner takes ~50 lines
|
|
190
|
+
|
|
191
|
+
Every scanner follows the same pattern:
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
# mcp_server/tools/my_scanner.py
|
|
195
|
+
from .installer import ensure_installed
|
|
196
|
+
|
|
197
|
+
async def scan(project_path: str) -> list[dict]:
|
|
198
|
+
if not await ensure_installed("my-tool"):
|
|
199
|
+
return [_not_installed_finding()]
|
|
200
|
+
# ... run subprocess, parse output, return findings
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
See `schemas/finding.json` for the unified finding schema all scanners must conform to.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Known-Bad Versions
|
|
208
|
+
|
|
209
|
+
The supply chain scanner ships with a blocklist that is updated as attacks are discovered:
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
# mcp_server/tools/supply_chain.py → KNOWN_BAD
|
|
213
|
+
[
|
|
214
|
+
{"name": "axios", "version": "1.14.1", "reason": "supply chain RAT March 2026"},
|
|
215
|
+
{"name": "axios", "version": "0.30.4", "reason": "supply chain RAT March 2026"},
|
|
216
|
+
{"name": "plain-crypto-js", "version": "4.2.1", "reason": "axios attack dropper"},
|
|
217
|
+
]
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
PRs to extend this list are welcome.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## License
|
|
225
|
+
|
|
226
|
+
MIT — free to use, modify, and distribute.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
<div align="center">
|
|
231
|
+
|
|
232
|
+
Built in response to the **March 2026 axios supply chain attack**.
|
|
233
|
+
Because `npm audit` wasn't enough.
|
|
234
|
+
|
|
235
|
+
</div>
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 🛡️ Security Autopilot
|
|
4
|
+
|
|
5
|
+
### The security scanner that works *while you code* — not after you ship.
|
|
6
|
+
|
|
7
|
+
[](tests/)
|
|
8
|
+
[](pyproject.toml)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://modelcontextprotocol.io)
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## The Problem
|
|
17
|
+
|
|
18
|
+
On **March 30, 2026**, two malicious versions of `axios` — one of the most downloaded npm packages on the planet — were quietly published to npm.
|
|
19
|
+
|
|
20
|
+
They contained **zero suspicious code inside axios itself**. Any developer who inspected the source would have found nothing wrong.
|
|
21
|
+
|
|
22
|
+
Instead, they silently injected a fake dependency called `plain-crypto-js` that ran a **postinstall script the moment you ran `npm install`**. That script phoned home to a command-and-control server and dropped a remote access trojan tailored to your OS.
|
|
23
|
+
|
|
24
|
+
After delivering the payload, it deleted itself and swapped its own `package.json` for a clean decoy. **No trace. No warning. No audit trail.**
|
|
25
|
+
|
|
26
|
+
`npm audit` reported nothing. GitHub Dependabot reported nothing. Standard code review caught nothing.
|
|
27
|
+
|
|
28
|
+
> **This is the new shape of supply chain attacks** — and your existing tools aren't built to catch them.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## What Security Autopilot Does
|
|
33
|
+
|
|
34
|
+
Security Autopilot is an **MCP server** that plugs directly into Claude Code and gives it real security scanning superpowers. You talk to Claude naturally — it runs the scans.
|
|
35
|
+
|
|
36
|
+
It catches the class of attacks that traditional tools miss:
|
|
37
|
+
|
|
38
|
+
| What it catches | How it catches it |
|
|
39
|
+
|---|---|
|
|
40
|
+
| 🔴 **Known-malicious packages** (axios@1.14.1, plain-crypto-js@4.2.1) | Blocklist checked before any install |
|
|
41
|
+
| 🟠 **Maintainer account hijacks** | Detects publisher email changes between versions |
|
|
42
|
+
| 🟠 **Postinstall script injection** | Flags any `preinstall`, `install`, `postinstall`, `prepare` lifecycle scripts |
|
|
43
|
+
| 🟡 **Recently published versions** | 72-hour cooldown gate on new releases |
|
|
44
|
+
| 🔵 **Floating version pins** | Flags `^` and `~` pins that allow silent upgrades |
|
|
45
|
+
| 🔵 **Missing SLSA provenance** | Detects packages published without cryptographic build attestations |
|
|
46
|
+
| 🟠 **Exposed secrets & credentials** | Gitleaks scans every file for hardcoded API keys, tokens, passwords |
|
|
47
|
+
| 🟡 **CVEs in your dependencies** | Trivy scans against the full NVD vulnerability database |
|
|
48
|
+
| 🟡 **Code-level security bugs** | Semgrep catches `eval(userInput)`, SQL injection, XSS, and 1000+ other patterns |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## How It Works
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
You type: "is my supply chain safe?"
|
|
56
|
+
│
|
|
57
|
+
▼
|
|
58
|
+
Claude Code calls scan_repo()
|
|
59
|
+
│
|
|
60
|
+
┌─────────┴──────────┐
|
|
61
|
+
│ 4 scanners run │ ← all in parallel, ~10 seconds total
|
|
62
|
+
│ simultaneously │
|
|
63
|
+
└─────────┬──────────┘
|
|
64
|
+
│
|
|
65
|
+
┌─────────┴────────────────────────────────────┐
|
|
66
|
+
│ Supply Chain │ Trivy │ Gitleaks │ Semgrep │
|
|
67
|
+
└─────────┬────────────────────────────────────┘
|
|
68
|
+
│
|
|
69
|
+
▼
|
|
70
|
+
Claude summarises findings in plain English
|
|
71
|
+
with severity, location, and exact fix steps
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Missing a scanner? **Security Autopilot installs it for you automatically** — no setup required.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Quick Start
|
|
79
|
+
|
|
80
|
+
### 1. Install (one command)
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
curl -fsSL https://get.securityautopilot.dev | sh
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This installs `uv`, the MCP server, all scanner CLIs (trivy, gitleaks, semgrep), and automatically patches `~/.claude/claude.json` to register the plugin. Safe to run twice.
|
|
87
|
+
|
|
88
|
+
> **Telemetry:** On first run you'll be asked whether to share anonymous usage data (OS + Python version). You can opt out at any time by deleting `~/.security-autopilot/telemetry_consent`.
|
|
89
|
+
|
|
90
|
+
### 2. Restart Claude Code
|
|
91
|
+
|
|
92
|
+
That's it — no manual config needed.
|
|
93
|
+
|
|
94
|
+
### 3. Just talk to Claude
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
"scan this project for security issues"
|
|
98
|
+
"any secrets exposed in this codebase?"
|
|
99
|
+
"is my supply chain safe?"
|
|
100
|
+
"check my dependencies for known vulnerabilities"
|
|
101
|
+
"watch this project and alert me to new issues"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## What a Scan Looks Like
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
## Security Scan: `/your/project`
|
|
110
|
+
Scanners: supply_chain, trivy, gitleaks, semgrep | Duration: 8.3s
|
|
111
|
+
Found: 4 issues — 🔴 1 critical 🟠 2 high 🟡 0 medium 🔵 1 low
|
|
112
|
+
|
|
113
|
+
### 🔴 [CRITICAL] Known-malicious package: axios@1.14.1
|
|
114
|
+
Location: package.json
|
|
115
|
+
Scanner: supply_chain
|
|
116
|
+
|
|
117
|
+
axios@1.14.1 is on the known-bad blocklist.
|
|
118
|
+
Reason: supply chain RAT March 2026 — postinstall dropper
|
|
119
|
+
|
|
120
|
+
Remediation: Remove axios@1.14.1 immediately. Downgrade to axios@1.14.0.
|
|
121
|
+
Rotate all secrets on affected machines — this version installs a
|
|
122
|
+
remote access trojan.
|
|
123
|
+
|
|
124
|
+
### 🟠 [HIGH] Exposed aws-secret-access-key secret in .env
|
|
125
|
+
Location: .env:3
|
|
126
|
+
Scanner: gitleaks
|
|
127
|
+
|
|
128
|
+
Rotate this credential immediately — assume it is compromised.
|
|
129
|
+
Add `.env` to .gitignore to prevent future commits.
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## MCP Tools
|
|
135
|
+
|
|
136
|
+
Claude gets access to 4 tools automatically:
|
|
137
|
+
|
|
138
|
+
| Tool | What it does |
|
|
139
|
+
|---|---|
|
|
140
|
+
| `scan_repo(path)` | Full scan — all 4 scanners in parallel |
|
|
141
|
+
| `scan_file(filepath)` | Scan a single file |
|
|
142
|
+
| `get_findings(severity)` | Retrieve cached findings from previous scans |
|
|
143
|
+
| `watch_project(path)` | Start a background daemon that re-scans on file changes |
|
|
144
|
+
|
|
145
|
+
The background watcher also sends a **desktop notification** the moment a new critical or high finding is detected — even if Claude Code isn't open.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Scanners
|
|
150
|
+
|
|
151
|
+
| Scanner | What it catches | Auto-installed? |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| **Supply Chain** | Known-bad versions, account hijacks, lifecycle scripts, floating pins, SLSA gaps | ✅ Built-in |
|
|
154
|
+
| **Trivy** | CVEs in npm, pip, Go, Rust, Java dependencies | ✅ Auto-installed |
|
|
155
|
+
| **Gitleaks** | Hardcoded secrets, API keys, tokens, passwords | ✅ Auto-installed |
|
|
156
|
+
| **Semgrep** | 1000+ SAST rules: injection, XSS, insecure patterns | ✅ Auto-installed |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## For Contributors
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Run tests
|
|
164
|
+
uv run pytest tests/ -v
|
|
165
|
+
|
|
166
|
+
# Start the MCP server manually
|
|
167
|
+
python -m mcp_server.server
|
|
168
|
+
|
|
169
|
+
# Add a new scanner
|
|
170
|
+
# → see CLAUDE.md for the exact pattern to follow
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Adding a scanner takes ~50 lines
|
|
174
|
+
|
|
175
|
+
Every scanner follows the same pattern:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
# mcp_server/tools/my_scanner.py
|
|
179
|
+
from .installer import ensure_installed
|
|
180
|
+
|
|
181
|
+
async def scan(project_path: str) -> list[dict]:
|
|
182
|
+
if not await ensure_installed("my-tool"):
|
|
183
|
+
return [_not_installed_finding()]
|
|
184
|
+
# ... run subprocess, parse output, return findings
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
See `schemas/finding.json` for the unified finding schema all scanners must conform to.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Known-Bad Versions
|
|
192
|
+
|
|
193
|
+
The supply chain scanner ships with a blocklist that is updated as attacks are discovered:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
# mcp_server/tools/supply_chain.py → KNOWN_BAD
|
|
197
|
+
[
|
|
198
|
+
{"name": "axios", "version": "1.14.1", "reason": "supply chain RAT March 2026"},
|
|
199
|
+
{"name": "axios", "version": "0.30.4", "reason": "supply chain RAT March 2026"},
|
|
200
|
+
{"name": "plain-crypto-js", "version": "4.2.1", "reason": "axios attack dropper"},
|
|
201
|
+
]
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
PRs to extend this list are welcome.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
MIT — free to use, modify, and distribute.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
<div align="center">
|
|
215
|
+
|
|
216
|
+
Built in response to the **March 2026 axios supply chain attack**.
|
|
217
|
+
Because `npm audit` wasn't enough.
|
|
218
|
+
|
|
219
|
+
</div>
|
|
File without changes
|