attackmap 0.1.1__tar.gz → 0.3.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.
- attackmap-0.3.0/PKG-INFO +604 -0
- attackmap-0.3.0/README.md +545 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/pyproject.toml +2 -1
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/__init__.py +1 -1
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/analyzer.py +51 -6
- attackmap-0.3.0/src/attackmap/analyzer_contracts.py +190 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/analyzers.py +183 -18
- attackmap-0.3.0/src/attackmap/anomalies.py +385 -0
- attackmap-0.3.0/src/attackmap/authz.py +196 -0
- attackmap-0.3.0/src/attackmap/cli.py +412 -0
- attackmap-0.3.0/src/attackmap/config_scanner.py +291 -0
- attackmap-0.3.0/src/attackmap/crypto.py +188 -0
- attackmap-0.3.0/src/attackmap/cve.py +436 -0
- attackmap-0.3.0/src/attackmap/diagrams.py +224 -0
- attackmap-0.3.0/src/attackmap/diff.py +179 -0
- attackmap-0.3.0/src/attackmap/exploitability.py +275 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/llm_review.py +34 -7
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/merge.py +39 -0
- attackmap-0.3.0/src/attackmap/models.py +661 -0
- attackmap-0.3.0/src/attackmap/progress.py +155 -0
- attackmap-0.3.0/src/attackmap/report.py +161 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/review_eval.py +70 -16
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/review_prompts.py +102 -0
- attackmap-0.3.0/src/attackmap/sarif.py +231 -0
- attackmap-0.3.0/src/attackmap/sbom.py +384 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/scanner.py +336 -16
- attackmap-0.3.0/src/attackmap/srcpaths.py +83 -0
- attackmap-0.3.0/src/attackmap/suggest.py +386 -0
- attackmap-0.3.0/src/attackmap/taint.py +491 -0
- attackmap-0.3.0/src/attackmap/threat_model.py +1882 -0
- attackmap-0.3.0/src/attackmap/topology.py +316 -0
- attackmap-0.3.0/src/attackmap/weaknesses.py +188 -0
- attackmap-0.3.0/src/attackmap/webhardening.py +142 -0
- attackmap-0.3.0/src/attackmap.egg-info/PKG-INFO +604 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap.egg-info/SOURCES.txt +39 -1
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap.egg-info/requires.txt +1 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_analyzer.py +101 -0
- attackmap-0.3.0/tests/test_analyzer_metadata_schema.py +194 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_analyzers.py +127 -10
- attackmap-0.3.0/tests/test_anomalies.py +371 -0
- attackmap-0.3.0/tests/test_authz.py +241 -0
- attackmap-0.3.0/tests/test_config_scanner.py +265 -0
- attackmap-0.3.0/tests/test_crypto.py +256 -0
- attackmap-0.3.0/tests/test_cve.py +403 -0
- attackmap-0.3.0/tests/test_diagrams.py +256 -0
- attackmap-0.3.0/tests/test_diff.py +368 -0
- attackmap-0.3.0/tests/test_exploitability.py +199 -0
- attackmap-0.3.0/tests/test_hunt.py +170 -0
- attackmap-0.3.0/tests/test_injection_sinks.py +247 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_llm_review.py +38 -0
- attackmap-0.3.0/tests/test_progress.py +97 -0
- attackmap-0.3.0/tests/test_provenance.py +208 -0
- attackmap-0.3.0/tests/test_review_eval.py +165 -0
- attackmap-0.3.0/tests/test_sarif.py +219 -0
- attackmap-0.3.0/tests/test_sbom.py +250 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_scanner.py +378 -0
- attackmap-0.3.0/tests/test_srcpaths.py +120 -0
- attackmap-0.3.0/tests/test_suggest.py +259 -0
- attackmap-0.3.0/tests/test_taint.py +247 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_threat_model.py +374 -2
- attackmap-0.3.0/tests/test_topology.py +220 -0
- attackmap-0.3.0/tests/test_weaknesses.py +255 -0
- attackmap-0.3.0/tests/test_webhardening.py +208 -0
- attackmap-0.1.1/PKG-INFO +0 -264
- attackmap-0.1.1/README.md +0 -206
- attackmap-0.1.1/src/attackmap/analyzer_contracts.py +0 -104
- attackmap-0.1.1/src/attackmap/cli.py +0 -185
- attackmap-0.1.1/src/attackmap/models.py +0 -352
- attackmap-0.1.1/src/attackmap/report.py +0 -74
- attackmap-0.1.1/src/attackmap/threat_model.py +0 -986
- attackmap-0.1.1/src/attackmap.egg-info/PKG-INFO +0 -264
- attackmap-0.1.1/tests/test_review_eval.py +0 -68
- {attackmap-0.1.1 → attackmap-0.3.0}/LICENSE +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/setup.cfg +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/asset_model.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/attack_taxonomy.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/context_pack.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/control_model.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/defensive_review.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/detection_opportunities.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/graph.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/insights.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/recon_models.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/recon_to_analysis.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/review_json.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/sdk/__init__.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/sdk/contracts.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/sdk/models.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap/security_overlay.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap.egg-info/dependency_links.txt +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap.egg-info/entry_points.txt +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/src/attackmap.egg-info/top_level.txt +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_artifact_schemas.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_context_pack.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_defensive_review.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_graph.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_merge.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_recon_to_analysis.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_report.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_review_json.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_review_prompts.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_security_overlay.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_shared_contract_imports.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_signal_v2.py +0 -0
- {attackmap-0.1.1 → attackmap-0.3.0}/tests/test_threat_intel.py +0 -0
attackmap-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: attackmap
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: AI-assisted defensive security analyzer for codebases — scans a repository, models assets and controls, finds cross-cutting weaknesses, and generates an evidence-grounded review with MITRE ATT&CK mappings and detection-engineering hints.
|
|
5
|
+
Author: AttackMap Contributors
|
|
6
|
+
Author-email: Matthew Davis <matthewd@matthewd.xyz>
|
|
7
|
+
Maintainer-email: Matthew Davis <matthewd@matthewd.xyz>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/mlaify/AttackMap
|
|
10
|
+
Project-URL: Documentation, https://github.com/mlaify/AttackMap/wiki
|
|
11
|
+
Project-URL: Repository, https://github.com/mlaify/AttackMap
|
|
12
|
+
Project-URL: Issues, https://github.com/mlaify/AttackMap/issues
|
|
13
|
+
Project-URL: Changelog, https://github.com/mlaify/AttackMap/blob/main/CHANGELOG.md
|
|
14
|
+
Keywords: security,static-analysis,appsec,defensive-security,threat-modeling,attack-surface,mitre-attack,detection-engineering,code-review,llm,claude
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Environment :: Console
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Information Technology
|
|
19
|
+
Classifier: Intended Audience :: System Administrators
|
|
20
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
27
|
+
Classifier: Topic :: Security
|
|
28
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
29
|
+
Classifier: Topic :: Software Development :: Testing
|
|
30
|
+
Classifier: Typing :: Typed
|
|
31
|
+
Requires-Python: >=3.11
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
License-File: LICENSE
|
|
34
|
+
Requires-Dist: typer>=0.12.3
|
|
35
|
+
Requires-Dist: pydantic>=2.7.0
|
|
36
|
+
Requires-Dist: networkx>=3.3
|
|
37
|
+
Provides-Extra: llm
|
|
38
|
+
Requires-Dist: anthropic>=0.40.0; extra == "llm"
|
|
39
|
+
Provides-Extra: all
|
|
40
|
+
Requires-Dist: attackmap[llm]; extra == "all"
|
|
41
|
+
Requires-Dist: attackmap-analyzer-python>=0.1.0; extra == "all"
|
|
42
|
+
Requires-Dist: attackmap-analyzer-rust>=0.1.0; extra == "all"
|
|
43
|
+
Requires-Dist: attackmap-analyzer-go>=0.1.0; extra == "all"
|
|
44
|
+
Requires-Dist: attackmap-analyzer-java-spring>=0.1.0; extra == "all"
|
|
45
|
+
Requires-Dist: attackmap-analyzer-dotnet>=0.1.0; extra == "all"
|
|
46
|
+
Requires-Dist: attackmap-analyzer-terraform>=0.1.0; extra == "all"
|
|
47
|
+
Requires-Dist: attackmap-analyzer-c>=0.1.0; extra == "all"
|
|
48
|
+
Requires-Dist: attackmap-analyzer-cpp>=0.1.0; extra == "all"
|
|
49
|
+
Requires-Dist: attackmap-analyzer-node-service>=0.2.0; extra == "all"
|
|
50
|
+
Requires-Dist: attackmap-analyzer-atproto>=0.1.0; extra == "all"
|
|
51
|
+
Requires-Dist: attackmap-analyzer-php-web>=0.1.0; extra == "all"
|
|
52
|
+
Requires-Dist: attackmap-analyzer-php-laminas>=0.1.0; extra == "all"
|
|
53
|
+
Requires-Dist: attackmap-analyzer-omeka-s>=0.1.0; extra == "all"
|
|
54
|
+
Requires-Dist: attackmap-analyzer-iac>=0.1.0; extra == "all"
|
|
55
|
+
Provides-Extra: dev
|
|
56
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
57
|
+
Requires-Dist: build>=1.2.0; extra == "dev"
|
|
58
|
+
Dynamic: license-file
|
|
59
|
+
|
|
60
|
+
# AttackMap
|
|
61
|
+
|
|
62
|
+
**AI-assisted defensive security analysis for codebases.** AttackMap reads your
|
|
63
|
+
repository, models its assets and defensive controls, traces request-to-sink
|
|
64
|
+
data flow, inventories dependencies and their known CVEs, and produces an
|
|
65
|
+
evidence-grounded security review with MITRE ATT&CK mappings and
|
|
66
|
+
detection-engineering hints — finding the cross-cutting weaknesses that
|
|
67
|
+
single-file scanners miss.
|
|
68
|
+
|
|
69
|
+
Built for AppSec engineers, SOC and detection-engineering teams, and engineering
|
|
70
|
+
managers who need to triage an unfamiliar codebase.
|
|
71
|
+
|
|
72
|
+
> Story over checklist. Asset-aware. Control-absence-aware. Evidence-grounded.
|
|
73
|
+
|
|
74
|
+
[](LICENSE)
|
|
75
|
+
[](https://www.python.org/)
|
|
76
|
+
[](https://pypi.org/project/attackmap/)
|
|
77
|
+
|
|
78
|
+
> **Status: beta (v0.3.0).** Core engine and 14 analyzer plugins are published
|
|
79
|
+
> to PyPI, Homebrew, and GHCR and validated against real-world codebases.
|
|
80
|
+
> AttackMap is heuristic by design — findings are confidence-tiered evidence,
|
|
81
|
+
> not proof. See [Project status](#project-status) for what's solid and what's
|
|
82
|
+
> still maturing.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Quickstart
|
|
87
|
+
|
|
88
|
+
Install with all bundled analyzers:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install "attackmap[all]"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Run a review on a repository:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
attackmap analyze /path/to/repo --output reports
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Optional: add an AI-narrated review using Claude. Either set an
|
|
101
|
+
`ANTHROPIC_API_KEY`, or log in once with the [Claude Code CLI](https://docs.claude.com/claude-code)
|
|
102
|
+
to use your existing Pro/Max subscription:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
attackmap analyze /path/to/repo --output reports --llm
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Read `reports/defensive-review.md` (heuristic) and `reports/defensive-review-llm.md`
|
|
109
|
+
(LLM-narrated) side by side.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Install
|
|
114
|
+
|
|
115
|
+
### From PyPI
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pip install attackmap # core only
|
|
119
|
+
pip install "attackmap[llm]" # add LLM narrative support
|
|
120
|
+
pip install "attackmap[all]" # core + LLM + all 14 analyzer plugins
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
You can also install individual analyzer plugins on demand:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
pip install attackmap-analyzer-python attackmap-analyzer-go
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Not sure which plugins your repo needs? Let AttackMap tell you:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
attackmap suggest ./path/to/repo # print ranked pip lines
|
|
133
|
+
attackmap suggest ./path/to/repo --install # and install them (prompts once)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`suggest` inspects the repo's manifest files, extensions, and directory layout
|
|
137
|
+
and recommends only the plugins that would give it deeper signal — useful
|
|
138
|
+
when you want a smaller install footprint than `[all]`.
|
|
139
|
+
|
|
140
|
+
### With Docker
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
docker run --rm -v "$PWD:/src" ghcr.io/mlaify/attackmap:latest analyze /src --output /src/reports
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### With Homebrew (macOS)
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
brew install mlaify/tap/attackmap
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### From source
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
git clone https://github.com/mlaify/AttackMap.git
|
|
156
|
+
cd AttackMap
|
|
157
|
+
pip install -e ".[llm]"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## What you get
|
|
163
|
+
|
|
164
|
+
Every `attackmap analyze` run writes:
|
|
165
|
+
|
|
166
|
+
| File | What it is |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `architecture.md` | High-level summary of the repository |
|
|
169
|
+
| `attack-surface.md` | Surfaces classified by category, exposure, and risk |
|
|
170
|
+
| `defensive-review.md` | Notable Observations, Asset Inventory, Defensive Controls, Strengths, Weaknesses, Detection Opportunities, Recommendations |
|
|
171
|
+
| `defensive-review.json` | Structured equivalent (schema v1.2.0) |
|
|
172
|
+
| `review-context-pack.json` | Structured evidence pack consumed by the LLM stage |
|
|
173
|
+
| `attackmap-report.json` | Everything bundled |
|
|
174
|
+
| `attackmap-report.sarif` | SARIF 2.1.0 log — ingestable by GitHub Code Scanning, VS Code, and other SARIF consumers |
|
|
175
|
+
| `attackmap-paths.md` | Mermaid flowcharts of each attack path — renders inline on GitHub |
|
|
176
|
+
| `attackmap-topology.md` | Mermaid graph of the service topology, with edge kinds styled per relationship type |
|
|
177
|
+
| `attackmap-paths.dot` / `attackmap-topology.dot` | Graphviz DOT versions of the two diagrams — feed into `dot -Tsvg` for slide-quality graphics |
|
|
178
|
+
| `attackmap-exploitability.md` | "Most exploitable now" — route→sink paths ranked by fused 0–100 score, each with its factors |
|
|
179
|
+
| `defensive-review-llm.md` *(with `--llm`)* | Claude-narrated review |
|
|
180
|
+
| `defensive-review-llm.meta.json` *(with `--llm`)* | Backend, model, token usage |
|
|
181
|
+
| `vulnerability-hypotheses.md` *(with `--hunt`)* | LLM-generated, evidence-cited exploit-chain **hypotheses** to confirm (leads, not detections) |
|
|
182
|
+
|
|
183
|
+
### GitHub Code Scanning integration
|
|
184
|
+
|
|
185
|
+
Drop this into `.github/workflows/attackmap.yml` to get AttackMap findings inline on every PR:
|
|
186
|
+
|
|
187
|
+
```yaml
|
|
188
|
+
name: AttackMap
|
|
189
|
+
on: [pull_request, push]
|
|
190
|
+
jobs:
|
|
191
|
+
scan:
|
|
192
|
+
runs-on: ubuntu-latest
|
|
193
|
+
permissions:
|
|
194
|
+
security-events: write
|
|
195
|
+
contents: read
|
|
196
|
+
steps:
|
|
197
|
+
- uses: actions/checkout@v4
|
|
198
|
+
- uses: actions/setup-python@v5
|
|
199
|
+
with: { python-version: "3.12" }
|
|
200
|
+
- run: pip install "attackmap[all]"
|
|
201
|
+
- run: attackmap analyze . --output reports
|
|
202
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
203
|
+
with:
|
|
204
|
+
sarif_file: reports/attackmap-report.sarif
|
|
205
|
+
category: attackmap
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Diff mode (PR gating)
|
|
209
|
+
|
|
210
|
+
For a lighter CI integration than Code Scanning — a bot comment, a JSON delta,
|
|
211
|
+
or a hard fail on newly-introduced HIGH findings — point `--baseline` at a
|
|
212
|
+
prior report and AttackMap will emit a Markdown diff alongside the fresh
|
|
213
|
+
report:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
attackmap analyze . --output reports \
|
|
217
|
+
--baseline path/to/previous/attackmap-report.json \
|
|
218
|
+
--diff-output reports/attackmap-diff.md \
|
|
219
|
+
--fail-on-new-high # exit non-zero if the PR introduces any HIGH finding
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Findings get a stable id (hash of the finding title) that survives line drift
|
|
223
|
+
on unrelated commits, so a finding that persists across scans has the same id
|
|
224
|
+
in both. The diff has three sections — **New**, **Persisted**, **Resolved** —
|
|
225
|
+
which drop cleanly into a PR comment.
|
|
226
|
+
|
|
227
|
+
### Data-flow / injection detection
|
|
228
|
+
|
|
229
|
+
A lightweight taint pass (Python + JS/TS) walks the import graph up to two hops
|
|
230
|
+
from each route handler and flags dangerous sinks reachable from an entry point.
|
|
231
|
+
Each sink kind that a route can reach produces a dedicated finding with an
|
|
232
|
+
ATT&CK mapping:
|
|
233
|
+
|
|
234
|
+
| Sink kind | What it catches | Severity |
|
|
235
|
+
|---|---|---|
|
|
236
|
+
| `eval` / `exec` | Request-reachable code execution | HIGH |
|
|
237
|
+
| `subprocess_shell` | OS command execution (`shell=True`, `child_process.exec`) | HIGH |
|
|
238
|
+
| `unsafe_deserialization` | `pickle.loads`, `yaml.load` (no SafeLoader), `marshal`, `node-serialize` | HIGH |
|
|
239
|
+
| `ssti` | Server-side template injection (`render_template_string`, `Template(req…)`) | HIGH |
|
|
240
|
+
| `ssrf` | Request-derived URL into `requests`/`httpx`/`urlopen`/`axios`/`fetch` | MEDIUM |
|
|
241
|
+
| `nosql_injection` | Request object as a Mongo filter, or `$where` | MEDIUM |
|
|
242
|
+
| `sql_execute` | Cursor/session `.execute`/`.query` reachable from a route | (feeds attack paths) |
|
|
243
|
+
| `dynamic_open` | `open()` with request-shaped path | (feeds attack paths) |
|
|
244
|
+
|
|
245
|
+
| `open_redirect` | Request-derived URL into `redirect()`/`res.redirect()` | MEDIUM |
|
|
246
|
+
|
|
247
|
+
Beyond the taint sinks, a per-file pass flags additional undisclosed-vuln
|
|
248
|
+
classes (`scan.code_weaknesses`): **prototype pollution** (`__proto__` writes,
|
|
249
|
+
deep-merge of a request object), **mass assignment** (a whole request body bound
|
|
250
|
+
to a model), **JWT weaknesses** (`alg=none`, signature verification off), **XXE**
|
|
251
|
+
(XML parsers with external entities enabled), **ReDoS** (regexes with
|
|
252
|
+
catastrophic backtracking), **insecure upload** (a file saved under a
|
|
253
|
+
client-controlled name/path), and **GraphQL exposure** (introspection/playground
|
|
254
|
+
left on).
|
|
255
|
+
|
|
256
|
+
Sinks that are only dangerous with attacker-controlled input (SSRF, SSTI, NoSQL,
|
|
257
|
+
open redirect, `open`) are gated on a request-shaped identifier in the call — a constant URL or
|
|
258
|
+
template is not flagged. It's a heuristic (import-edge ≠ call-edge), so findings
|
|
259
|
+
are evidence, not proof; confidence tapers with hop distance. Chains appear in
|
|
260
|
+
`attackmap-report.json` under `scan.taint_chains`.
|
|
261
|
+
|
|
262
|
+
Test and spec files (`tests/`, `__tests__/`, `*.test.*`, `test_*.py`, …) are
|
|
263
|
+
excluded from all the heuristic passes above by default, since dangerous
|
|
264
|
+
patterns in test scaffolding are rarely real exposure. Set
|
|
265
|
+
`ATTACKMAP_INCLUDE_TESTS=1` to scan them too (e.g. for test-quality reviews).
|
|
266
|
+
|
|
267
|
+
### Web hardening gaps
|
|
268
|
+
|
|
269
|
+
Route- and config-level checks for common web misconfigurations, each an
|
|
270
|
+
ATT&CK-mapped finding:
|
|
271
|
+
|
|
272
|
+
| Kind | Catches | Severity |
|
|
273
|
+
|---|---|---|
|
|
274
|
+
| `cors_wildcard_credentials` | wildcard/reflected CORS origin **with** credentials | HIGH |
|
|
275
|
+
| `csrf_disabled` | CSRF explicitly disabled / exempted | MEDIUM |
|
|
276
|
+
| `insecure_cookie` | `httpOnly:false`, `secure:false`, `SameSite=None` without `Secure` | MEDIUM |
|
|
277
|
+
| `weak_csp` | CSP allowing `'unsafe-inline'` / `'unsafe-eval'` | MEDIUM |
|
|
278
|
+
| `debug_enabled` | debug mode / actuator wildcard exposure shipped on | MEDIUM |
|
|
279
|
+
|
|
280
|
+
These detect *positively-present* misconfigurations rather than hard-to-judge
|
|
281
|
+
absences (a wildcard CORS origin alone is fine — it's the pairing with
|
|
282
|
+
credentials that's flagged). Results appear under `scan.web_hardening_issues`.
|
|
283
|
+
|
|
284
|
+
### Insecure cryptography & weak randomness
|
|
285
|
+
|
|
286
|
+
A cheap per-file pass flags crypto misuse, each as a finding with an ATT&CK
|
|
287
|
+
mapping:
|
|
288
|
+
|
|
289
|
+
| Kind | Catches | Severity |
|
|
290
|
+
|---|---|---|
|
|
291
|
+
| `weak_password_hash` | MD5/SHA-1 over a password-shaped value | HIGH |
|
|
292
|
+
| `weak_cipher` | DES / 3DES / RC4 / Blowfish | HIGH |
|
|
293
|
+
| `ecb_mode` | ECB block-cipher mode (incl. Java's `Cipher.getInstance("AES")` default) | MEDIUM |
|
|
294
|
+
| `static_iv_salt` | hard-coded IV or salt literal | MEDIUM |
|
|
295
|
+
| `insecure_random` | `Math.random`/`random`/`rand`/`mt_rand` for a token/key/salt/nonce | MEDIUM |
|
|
296
|
+
| `insecure_tls` | `verify=False`, `rejectUnauthorized:false`, `InsecureSkipVerify:true`, deprecated TLS | HIGH |
|
|
297
|
+
|
|
298
|
+
The noisy families (weak hash, insecure RNG) are gated on a security-context
|
|
299
|
+
identifier; cipher/ECB tokens are matched case-sensitively so algorithm names
|
|
300
|
+
aren't confused with prose (e.g. the French word "des"). Results appear under
|
|
301
|
+
`scan.crypto_weaknesses`.
|
|
302
|
+
|
|
303
|
+
### Broken object-level authorization (BOLA / IDOR)
|
|
304
|
+
|
|
305
|
+
OWASP API Security #1. AttackMap flags a route as a BOLA/IDOR candidate when it
|
|
306
|
+
composes three signals it already has:
|
|
307
|
+
|
|
308
|
+
1. the route takes a **resource id** in the path (`/users/{id}`,
|
|
309
|
+
`/orders/:orderId`, `/docs/<int:doc_id>`), and
|
|
310
|
+
2. it **reaches a datastore** — a DB hint in the same file/module, or a taint
|
|
311
|
+
chain from the route to a SQL execute sink, and
|
|
312
|
+
3. **no ownership/authorization check** is visible near the handler
|
|
313
|
+
(`current_user`, `request.user`, `authorize`, a policy/guard, or a
|
|
314
|
+
`filter_by(user_id=…)`-style scoped query).
|
|
315
|
+
|
|
316
|
+
Write routes (POST/PUT/PATCH/DELETE) are HIGH, reads MEDIUM. Candidates appear
|
|
317
|
+
under `scan.authz_candidates`; the ownership-marker scan is the main
|
|
318
|
+
false-positive reducer, so a well-scoped handler is not flagged. Path-template
|
|
319
|
+
routes today; query-parameter and RPC-method ids are future work.
|
|
320
|
+
|
|
321
|
+
### Anomaly / outlier detection
|
|
322
|
+
|
|
323
|
+
The closest honest thing to "surface the unknown": instead of matching a
|
|
324
|
+
known-bad signature, AttackMap flags a route that deviates from the norm its own
|
|
325
|
+
siblings establish. Routes are bucketed into resource cohorts by path prefix
|
|
326
|
+
(`/api/users`, `/api/users/{id}` and `/api/users/export` all share `api/users`;
|
|
327
|
+
`api`/version scaffolding is stripped so versioned resources still separate), and
|
|
328
|
+
within each cohort the odd-one-out is reported:
|
|
329
|
+
|
|
330
|
+
| Kind | Catches | Severity |
|
|
331
|
+
|---|---|---|
|
|
332
|
+
| `auth_outlier` | siblings carry an auth/authorization signal near the handler; this route doesn't | HIGH |
|
|
333
|
+
| `validation_outlier` | among a cohort's state-changing handlers, peers validate input and this one shows no validation marker | LOW |
|
|
334
|
+
| `method_outlier` | a lone state-changing method in an otherwise read-only cohort | MEDIUM |
|
|
335
|
+
|
|
336
|
+
Everything is peer-relative and **confidence scales with how consistent the
|
|
337
|
+
cohort is** — a lone deviation among many agreeing siblings is likelier a mistake
|
|
338
|
+
than the same deviation in a split group. Outliers are only flagged when they're a
|
|
339
|
+
strict minority (a genuinely 50/50 surface isn't nagged), the cohort must have
|
|
340
|
+
real route structure (distinct paths with parameters/sub-paths, not repeated
|
|
341
|
+
method-call strings), and per-route signal detection is scoped to each handler's
|
|
342
|
+
own span so a sibling's guard is never miscredited. Results appear under
|
|
343
|
+
`scan.anomalies`, each finding naming the peer group and the deviation. This is
|
|
344
|
+
the scan-level, route-cohort counterpart to the layered engine's
|
|
345
|
+
`asymmetric_protection` insight.
|
|
346
|
+
|
|
347
|
+
### Exploitability fusion ("Most exploitable now")
|
|
348
|
+
|
|
349
|
+
Every signal AttackMap has about a route→sink path is fused into a single
|
|
350
|
+
**0–100 exploitability score** so the highest-risk *combinations* rise to the
|
|
351
|
+
top — the public, unauthenticated route whose request reaches a SQL sink next to
|
|
352
|
+
a secret is a different animal from an internal, authed route that reaches the
|
|
353
|
+
same sink two hops away. The score is:
|
|
354
|
+
|
|
355
|
+
- **Deterministic** — the same scan always yields the same number; no
|
|
356
|
+
randomness, no clock.
|
|
357
|
+
- **Explainable** — the score is the clamped sum of named factors, and every one
|
|
358
|
+
is shown. Contributing factors: sink danger (SQLi/RCE/deserialization highest),
|
|
359
|
+
exposure (public/internal/unknown), auth at the entry route, reachability
|
|
360
|
+
(fewer hops = higher), and data sensitivity at the sink (a co-located secret or
|
|
361
|
+
datastore), plus insecure-crypto / web-hardening gaps on the path as
|
|
362
|
+
amplifiers.
|
|
363
|
+
|
|
364
|
+
Scores land on the relevant taint findings (`exploitability` + `exploitability_tier`)
|
|
365
|
+
and in a ranked **`attackmap-exploitability.md`** report plus the `exploitability`
|
|
366
|
+
array in `attackmap-report.json`; the console summary leads with the top few. For
|
|
367
|
+
example, `public + no-auth + taint-to-eval (0 hops)` scores 90/100 (CRITICAL).
|
|
368
|
+
(Dependency CVEs are manifest-level, not attributable to a specific source path,
|
|
369
|
+
so they inform the report but aren't folded into a path's score — path-attributed
|
|
370
|
+
CVE fusion is future work.)
|
|
371
|
+
|
|
372
|
+
### SBOM inventory
|
|
373
|
+
|
|
374
|
+
Every scan also produces a lightweight SBOM by parsing direct dependencies out
|
|
375
|
+
of the common manifest files:
|
|
376
|
+
|
|
377
|
+
| Ecosystem | Files parsed |
|
|
378
|
+
|---|---|
|
|
379
|
+
| PyPI (Python) | `pyproject.toml` (PEP 621 + Poetry), `requirements.txt` |
|
|
380
|
+
| npm (Node.js) | `package.json` (dependencies + devDependencies + peer/optional) |
|
|
381
|
+
| Go | `go.mod` (single-line + block-form `require`, `// indirect` flagged) |
|
|
382
|
+
| Cargo (Rust) | `Cargo.toml` (dependencies + dev-dependencies + build-dependencies) |
|
|
383
|
+
| Composer (PHP) | `composer.json` (require + require-dev; platform reqs skipped) |
|
|
384
|
+
|
|
385
|
+
Each entry appears in `attackmap-report.json` under `scan.dependencies` with
|
|
386
|
+
`{name, version, ecosystem, file, dev}`. Version ranges are kept verbatim
|
|
387
|
+
(`^4.16.0`, `>=2,<3`, `latest`) — this slice does not resolve lockfiles.
|
|
388
|
+
|
|
389
|
+
### CVE cross-reference (opt-in)
|
|
390
|
+
|
|
391
|
+
`attackmap analyze --cve` cross-references every SBOM entry against
|
|
392
|
+
[OSV.dev](https://osv.dev) and emits one finding per vulnerable dependency
|
|
393
|
+
(all known advisories aggregated in the evidence list). CVSS scores map into
|
|
394
|
+
low/medium/high — anything ≥ 7.0 is HIGH.
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
attackmap analyze . --cve
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
- **Off by default.** The flag exists precisely because CVE lookup does
|
|
401
|
+
network I/O; regular scans stay offline.
|
|
402
|
+
- **Cached** under `~/.attackmap/cache/osv/` keyed by
|
|
403
|
+
`sha256(ecosystem+name+version)`. TTL is 24h by default, overridable via
|
|
404
|
+
`ATTACKMAP_OSV_CACHE_TTL_HOURS`. Repeat scans of the same repo don't hit
|
|
405
|
+
the network.
|
|
406
|
+
- **Offline-tolerant.** If the network's unavailable but the cache is warm,
|
|
407
|
+
cached results still surface; only fresh queries are skipped.
|
|
408
|
+
- **Version resolution is best-effort.** Manifest ranges (`^4.16.0`,
|
|
409
|
+
`>=2.28,<3`) resolve to a queryable lower-bound; OSV does the range math.
|
|
410
|
+
Unpinned specs (`*`, `latest`) are skipped.
|
|
411
|
+
|
|
412
|
+
The structured vulnerability list is available under
|
|
413
|
+
`scan.vulnerabilities` in `attackmap-report.json` with
|
|
414
|
+
`{id, aliases, summary, severity, cvss_score, references, affected_range,
|
|
415
|
+
package_name, package_version, ecosystem}`.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## How it works
|
|
420
|
+
|
|
421
|
+
AttackMap is built as four layers, each grounded in the layer below.
|
|
422
|
+
|
|
423
|
+
**1. Heuristic scanner + analyzer plugins.** Language-aware extraction of routes,
|
|
424
|
+
databases, external calls, auth signals, secrets, frameworks, and entrypoints.
|
|
425
|
+
Every signal carries a `file:line` citation, an evidence-text snippet, and a
|
|
426
|
+
confidence score. Plugins are auto-discovered through the `attackmap.analyzers`
|
|
427
|
+
entry-point group. Alongside recon, three cross-file passes run in core: a
|
|
428
|
+
**taint / data-flow** walk (request-to-sink reachability across imports), a
|
|
429
|
+
**BOLA/IDOR** authorization check, and an **SBOM** dependency inventory
|
|
430
|
+
(optionally cross-referenced against OSV.dev with `--cve`).
|
|
431
|
+
|
|
432
|
+
**2. Asset and control overlay.** Identifies *what's at risk* (credentials,
|
|
433
|
+
sessions, PII, payment records, internal secrets — with criticality tiers) and
|
|
434
|
+
*what protects it* (authentication, authorization, input validation, rate
|
|
435
|
+
limiting, CSRF, encryption, audit logging, RBAC, MFA), including detection of
|
|
436
|
+
*absent* expected controls.
|
|
437
|
+
|
|
438
|
+
**3. Cross-cutting insight engine.** Connects findings into narratives —
|
|
439
|
+
sensitive-asset reachability, shared-secret blast radius, defense gaps in attack
|
|
440
|
+
chains, control-strength mismatches, asymmetric protection, audit gaps,
|
|
441
|
+
trust-boundary violations, and more.
|
|
442
|
+
|
|
443
|
+
**4. LLM narrative review.** With `--llm`, Claude Opus generates a final review
|
|
444
|
+
from the structured evidence pack. The model is forced to cite real
|
|
445
|
+
surface/asset/control IDs, so it can't invent findings.
|
|
446
|
+
|
|
447
|
+
**5. Vulnerability-hypothesis hunting (`--hunt`).** The honest core of the
|
|
448
|
+
"find the unknown" ask. `attackmap analyze . --hunt` has Claude reason over the
|
|
449
|
+
full evidence pack (surfaces, assets, controls, taint chains, exploitability
|
|
450
|
+
scores, anomalies) as a red-team analyst and propose **ranked, human-verifiable
|
|
451
|
+
exploit-chain hypotheses** — candidate weaknesses a static rule wouldn't catch,
|
|
452
|
+
especially novel cross-signal combinations. Output goes to
|
|
453
|
+
`vulnerability-hypotheses.md` under an unmissable banner: **these are hypotheses
|
|
454
|
+
to confirm, not detections.** The same grounding contract as the review applies
|
|
455
|
+
(every hypothesis cites real evidence IDs), plus honesty guardrails: no CVE
|
|
456
|
+
assignment, no exploit code, confidence-tiered, and each lead lists exactly what
|
|
457
|
+
a human must verify. Uses the same auth/backend resolution as `--llm`.
|
|
458
|
+
|
|
459
|
+
Layered on top: **MITRE ATT&CK technique mappings** on every insight and
|
|
460
|
+
**detection opportunities** (Sigma/KQL/Splunk-style hints) for each weakness.
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Supported ecosystems
|
|
465
|
+
|
|
466
|
+
Fourteen official analyzer plugins, each distributable as a separate package:
|
|
467
|
+
|
|
468
|
+
| Plugin | Coverage |
|
|
469
|
+
|---|---|
|
|
470
|
+
| `attackmap-analyzer-python` | Django, Starlette, AIOHTTP, Sanic, Litestar, DRF; SQLAlchemy/asyncpg/motor; passlib/PyJWT/authlib; httpx/aiohttp |
|
|
471
|
+
| `attackmap-analyzer-rust` | axum, actix-web, rocket; sqlx, diesel, sea-orm; jsonwebtoken, argon2; reqwest |
|
|
472
|
+
| `attackmap-analyzer-go` | net/http, chi, gin, echo, fiber, gorilla/mux; database/sql, gorm, pgx; golang-jwt; resty |
|
|
473
|
+
| `attackmap-analyzer-java-spring` | Java/Kotlin Spring Boot, JAX-RS, Ktor; Spring Data; Spring Security; jjwt |
|
|
474
|
+
| `attackmap-analyzer-dotnet` | ASP.NET Core minimal APIs and attribute routing, EF Core, Identity, JwtBearer |
|
|
475
|
+
| `attackmap-analyzer-terraform` | AWS, Azure, GCP resources; IAM wildcards; open SGs; secrets |
|
|
476
|
+
| `attackmap-analyzer-iac` | Dockerfile hardening, docker-compose service graphs, GitHub Actions workflows, `.env` templates, shell installers |
|
|
477
|
+
| `attackmap-analyzer-c` | libmicrohttpd, civetweb, mongoose; libcurl; OpenSSL/libsodium; sqlite3/libpq/mysql |
|
|
478
|
+
| `attackmap-analyzer-cpp` | Crow, Pistache, Drogon, cpprestsdk; libcurl/cpr; OpenSSL/Botan/libsodium; libpqxx/mongocxx |
|
|
479
|
+
| `attackmap-analyzer-node-service` | Node.js / TypeScript service ecosystems |
|
|
480
|
+
| `attackmap-analyzer-atproto` | AT Protocol (Bluesky) services |
|
|
481
|
+
| `attackmap-analyzer-php-web` / `-php-laminas` / `-omeka-s` | Generic PHP web, Laminas/Zend MVC, Omeka-S |
|
|
482
|
+
|
|
483
|
+
`pip install "attackmap[all]"` installs every official plugin. Not sure which
|
|
484
|
+
you need? `attackmap suggest ./repo` recommends the right set for a repo's shape.
|
|
485
|
+
|
|
486
|
+
### Building your own analyzer
|
|
487
|
+
|
|
488
|
+
The plugin contract is documented in code at
|
|
489
|
+
[`attackmap.sdk`](src/attackmap/sdk/__init__.py); the developer cookbook with
|
|
490
|
+
scaffolding, testing, and publishing instructions is in
|
|
491
|
+
[`docs/external-analyzers.md`](docs/external-analyzers.md).
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## CLI reference
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
attackmap analyze <path> # run a review on a repository
|
|
499
|
+
attackmap analyze <path> --output dir # write outputs to `dir/`
|
|
500
|
+
attackmap analyze <path> --format json # json | markdown | all (default)
|
|
501
|
+
attackmap analyze <path> --module python --module rust # only these analyzers
|
|
502
|
+
attackmap analyze <path> --cve # cross-reference SBOM against OSV.dev
|
|
503
|
+
attackmap analyze <path> --llm # add LLM narrative (auto-resolve auth)
|
|
504
|
+
attackmap analyze <path> --llm --llm-backend cli # force Claude CLI
|
|
505
|
+
attackmap analyze <path> --hunt # LLM vulnerability-hypothesis hunt (leads to confirm)
|
|
506
|
+
|
|
507
|
+
# CI / PR diff gating
|
|
508
|
+
attackmap analyze <path> --baseline prev/attackmap-report.json \
|
|
509
|
+
--diff-output reports/attackmap-diff.md --fail-on-new-high
|
|
510
|
+
|
|
511
|
+
# Plugin discovery
|
|
512
|
+
attackmap suggest ./repo # recommend plugins for a repo shape
|
|
513
|
+
attackmap suggest ./repo --install # and pip-install the missing ones
|
|
514
|
+
attackmap modules # list installed analyzers
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
`--module` is repeatable. Missing requested external analyzers can be
|
|
518
|
+
auto-installed (when possible) from the `mlaify` GitHub organization. `--cve`
|
|
519
|
+
does network I/O (cached under `~/.attackmap/cache/osv/`, 24h TTL);
|
|
520
|
+
`--fail-on-new-high` requires `--baseline` and exits non-zero when the diff
|
|
521
|
+
introduces a new HIGH finding.
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## What AttackMap is *not*
|
|
526
|
+
|
|
527
|
+
- **A runtime detector.** AttackMap is static. The detection opportunities it
|
|
528
|
+
emits are *hints* for your SIEM team — they are not deployable rules.
|
|
529
|
+
- **A replacement for dedicated SCA.** AttackMap does inventory dependencies and
|
|
530
|
+
cross-reference OSV.dev with `--cve`, but tools like Trivy, Grype, and
|
|
531
|
+
Dependabot go deeper on transitive resolution and lockfiles. AttackMap's
|
|
532
|
+
value is folding the CVE signal into an architecture-aware narrative
|
|
533
|
+
("this public route reaches this vulnerable ORM").
|
|
534
|
+
- **A true taint engine.** The data-flow pass is a heuristic import-graph walk
|
|
535
|
+
(import-edge ≈ call-edge), not sound interprocedural taint analysis. It
|
|
536
|
+
favors precision over recall; findings are evidence, not proof.
|
|
537
|
+
- **Exhaustive.** AttackMap is heuristic by design. Findings are confidence-tiered
|
|
538
|
+
with explicit guardrails for stale signals.
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
## Project status
|
|
543
|
+
|
|
544
|
+
AttackMap is **beta** (v0.3.0) — published and validated on real codebases, but
|
|
545
|
+
pre-1.0 and heuristic.
|
|
546
|
+
|
|
547
|
+
**Solid today:**
|
|
548
|
+
|
|
549
|
+
- Modular analyzer execution with entry-point discovery; 14 official plugins on PyPI.
|
|
550
|
+
- Framework-aware route extraction (FastAPI/Flask/Express/Spring/axum/chi/…).
|
|
551
|
+
- Asset + control modeling, cross-cutting insight engine, chain-aware threat model.
|
|
552
|
+
- Injection / data-flow detection: SSRF, SSTI, NoSQL, unsafe deserialization,
|
|
553
|
+
eval/exec/shell, SQL, dynamic file open, open redirect — request-container-gated
|
|
554
|
+
for precision.
|
|
555
|
+
- Novel vuln-class detectors: prototype pollution, mass assignment, JWT weakness,
|
|
556
|
+
XXE, ReDoS, insecure upload, GraphQL exposure.
|
|
557
|
+
- BOLA/IDOR authorization detection on path-template routes.
|
|
558
|
+
- Insecure-crypto / weak-randomness and web-hardening (CORS/CSRF/cookies/CSP/debug)
|
|
559
|
+
detection.
|
|
560
|
+
- Anomaly / outlier detection (the odd-one-out among sibling routes) and
|
|
561
|
+
**exploitability fusion** — a deterministic, explainable 0–100 "exploitable now"
|
|
562
|
+
score that ranks route→sink combinations.
|
|
563
|
+
- **`--hunt`**: LLM vulnerability-hypothesis mode — evidence-cited, human-verifiable
|
|
564
|
+
exploit-chain leads (not detections).
|
|
565
|
+
- SBOM inventory (5 ecosystems) + OSV.dev CVE cross-reference (`--cve`).
|
|
566
|
+
- Output: Markdown + JSON + **SARIF 2.1.0** (GitHub Code Scanning) + **Mermaid /
|
|
567
|
+
Graphviz** diagrams; **diff/baseline** mode for PR gating; optional LLM narrative.
|
|
568
|
+
- Live scan progress bar + ETA; test/spec files excluded from heuristic passes.
|
|
569
|
+
- Distribution: `pip install attackmap[all]`, `brew install mlaify/tap/attackmap`,
|
|
570
|
+
`docker pull ghcr.io/mlaify/attackmap`.
|
|
571
|
+
|
|
572
|
+
**Still maturing:**
|
|
573
|
+
|
|
574
|
+
- Taint + BOLA are Python + JS/TS and path-template scoped; query-param / RPC-method
|
|
575
|
+
authorization and more languages are planned.
|
|
576
|
+
- The import-graph taint walk approximates call-edges with import-edges — precision
|
|
577
|
+
over recall; findings are evidence, not proof.
|
|
578
|
+
- CVE lookup resolves a best-effort concrete version, not full lockfile ranges, and
|
|
579
|
+
isn't yet fused into per-path exploitability scores.
|
|
580
|
+
- Anomaly / exploitability reasoning is route-cohort and taint-chain scoped.
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## Documentation
|
|
585
|
+
|
|
586
|
+
- [`CHANGELOG.md`](CHANGELOG.md) — release notes
|
|
587
|
+
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — development setup and PR process
|
|
588
|
+
- [`SECURITY.md`](SECURITY.md) — vulnerability disclosure
|
|
589
|
+
- [`AGENTS.md`](AGENTS.md) — agent-facing repo guide
|
|
590
|
+
- [`VISION.md`](VISION.md) — project direction
|
|
591
|
+
- [GitHub wiki](https://github.com/mlaify/AttackMap/wiki) — deeper architecture
|
|
592
|
+
and analyzer-contract references
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Contributing
|
|
597
|
+
|
|
598
|
+
Issues and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
599
|
+
for setup, testing, and submission guidelines. By contributing you agree that
|
|
600
|
+
your contributions will be MIT-licensed.
|
|
601
|
+
|
|
602
|
+
## License
|
|
603
|
+
|
|
604
|
+
[MIT](LICENSE). Copyright (c) 2026 Matthew Davis and AttackMap Contributors.
|