mcp-api-pentest 0.2.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.
- mcp_api_pentest-0.2.0/LICENSE +21 -0
- mcp_api_pentest-0.2.0/MANIFEST.in +2 -0
- mcp_api_pentest-0.2.0/PKG-INFO +288 -0
- mcp_api_pentest-0.2.0/README.md +257 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/adapters/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/adapters/cli.py +65 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/adapters/mcp_server.py +50 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/adapters/tests/test_cli.py +122 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/audit_context/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/audit_context/attack_context.py +101 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/audit_context/tests/__init__.py +1 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/audit_context/tests/test_attack_context.py +134 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/config/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/config/settings.py +13 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/http_client/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/http_client/auth/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/http_client/auth/bearer_auth.py +18 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/http_client/http_client.py +84 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/http_client/tests/test_http_client.py +89 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/idor_detector/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/idor_detector/access_analyzer.py +126 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/idor_detector/tests/test_access_analyzer.py +58 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/idor_detector/tests/test_volatile_cleaner.py +41 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/idor_detector/volatile_cleaner.py +19 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/orchestration/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/orchestration/audit_pipeline.py +22 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/report_generator/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/report_generator/finding.py +24 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/report_generator/markdown_reporter.py +110 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/report_generator/reporter.py +43 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/report_generator/tests/test_reporter.py +123 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/shared/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/shared/json_truncator.py +18 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/shared/tests/test_json_truncator.py +125 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/spec_analyzer/__init__.py +0 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/spec_analyzer/spec_parser.py +47 -0
- mcp_api_pentest-0.2.0/mcp_api_logic_pentest/spec_analyzer/tests/test_spec_parser.py +86 -0
- mcp_api_pentest-0.2.0/mcp_api_pentest.egg-info/PKG-INFO +288 -0
- mcp_api_pentest-0.2.0/mcp_api_pentest.egg-info/SOURCES.txt +45 -0
- mcp_api_pentest-0.2.0/mcp_api_pentest.egg-info/dependency_links.txt +1 -0
- mcp_api_pentest-0.2.0/mcp_api_pentest.egg-info/entry_points.txt +2 -0
- mcp_api_pentest-0.2.0/mcp_api_pentest.egg-info/requires.txt +4 -0
- mcp_api_pentest-0.2.0/mcp_api_pentest.egg-info/top_level.txt +1 -0
- mcp_api_pentest-0.2.0/pyproject.toml +66 -0
- mcp_api_pentest-0.2.0/setup.cfg +4 -0
- mcp_api_pentest-0.2.0/tests/test_mock_api.py +107 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mcp-api-logic-pentest
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-api-pentest
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: MCP server for autonomous API logic penetration testing — OWASP API Top 10 / BOLA-IDOR detection via LLM-driven analysis
|
|
5
|
+
Author-email: Jose Nieto <josenieto@github.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/josenieto/mcp-api-logic-pentest
|
|
8
|
+
Project-URL: Repository, https://github.com/josenieto/mcp-api-logic-pentest
|
|
9
|
+
Project-URL: Issues, https://github.com/josenieto/mcp-api-logic-pentest/issues
|
|
10
|
+
Keywords: mcp,pentest,api-security,owasp,bola,idor,security-audit
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Security
|
|
22
|
+
Classifier: Topic :: Software Development :: Testing
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: fastapi>=0.139.2
|
|
27
|
+
Requires-Dist: fastmcp>=3.4.4
|
|
28
|
+
Requires-Dist: httpx>=0.28.1
|
|
29
|
+
Requires-Dist: uvicorn>=0.51.0
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# mcp-api-pentest
|
|
33
|
+
|
|
34
|
+
An MCP server that lets AI assistants (Claude Desktop, Cursor, Claude Code) perform automated security audits on your APIs. It detects **BOLA/IDOR** vulnerabilities — the #1 risk in the OWASP API Top 10 — where one user can access another user's data.
|
|
35
|
+
|
|
36
|
+
> Think of it as giving your AI the ability to act like a penetration tester, running requests with different user tokens and comparing the results to find broken authorization logic.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quickstart in 3 minutes
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# 1. Clone and install
|
|
44
|
+
git clone https://github.com/josenieto/mcp-api-pentest
|
|
45
|
+
cd mcp-api-pentest
|
|
46
|
+
uv sync
|
|
47
|
+
|
|
48
|
+
# 2. Start the mock API (a vulnerable API for safe testing)
|
|
49
|
+
uv run mock_api.py
|
|
50
|
+
|
|
51
|
+
# 3. Start the MCP server
|
|
52
|
+
uv run app.py
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
That's it. The server is now running and waiting for an AI client to connect.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## What it does
|
|
60
|
+
|
|
61
|
+
The project acts as a bridge between an AI and your API:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
AI (Claude/Cursor) ←→ MCP Server ←→ API Target
|
|
65
|
+
|
|
|
66
|
+
Generates REPORTE_PENTEST.md
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Example attack flow the AI can run:**
|
|
70
|
+
|
|
71
|
+
1. **Create** an invoice with Token A → `POST /api/v1/invoices`
|
|
72
|
+
2. **Read** the same invoice with Token B → `GET /api/v1/invoices/42`
|
|
73
|
+
3. **Detect** the IDOR → both tokens return 200 OK with 94% similar content
|
|
74
|
+
4. **Save** the finding → "BOLA/IDOR in invoices endpoint — CRITICAL"
|
|
75
|
+
5. **Generate** a report → `REPORTE_PENTEST.md`
|
|
76
|
+
|
|
77
|
+
All of this happens without writing a single line of code — the AI drives the audit through MCP tools.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Features
|
|
82
|
+
|
|
83
|
+
- **IDOR detection**: Compares API responses with privileged vs unprivileged tokens
|
|
84
|
+
- **Chained attacks**: Create a resource, capture its ID, then attack it with a different user
|
|
85
|
+
- **Multi-session state**: Cache dynamic values across requests for complex attack flows
|
|
86
|
+
- **Smart truncation**: Handles massive JSON responses without flooding the AI's context window
|
|
87
|
+
- **Rate limiting**: Passive delays to avoid being blocked by WAFs
|
|
88
|
+
- **Markdown reports**: Automatic generation of security audit reports with evidence
|
|
89
|
+
- **Mock API sandbox**: 7 intentionally vulnerable endpoints for safe testing
|
|
90
|
+
- **CLI entry point**: Run from the terminal with `mcp-api-pentest --target https://api.example.com`
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Installation
|
|
95
|
+
|
|
96
|
+
### From source (recommended for now)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
git clone https://github.com/josenieto/mcp-api-pentest
|
|
100
|
+
cd mcp-api-pentest
|
|
101
|
+
uv sync
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Requirements
|
|
105
|
+
|
|
106
|
+
- Python 3.10 or newer
|
|
107
|
+
- [uv](https://github.com/astral-sh/uv) package manager
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## How to Use
|
|
112
|
+
|
|
113
|
+
### Option 1: CLI mode (terminal)
|
|
114
|
+
|
|
115
|
+
Start the MCP server directly:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
uv run app.py
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
With options:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
mcp-api-pentest \
|
|
125
|
+
--swagger spec.json \
|
|
126
|
+
--target https://api.example.com \
|
|
127
|
+
--token-admin "admin123" \
|
|
128
|
+
--token-victim "victim456" \
|
|
129
|
+
--token-attacker "attacker789" \
|
|
130
|
+
--output report.md \
|
|
131
|
+
--delay 1.0
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Option 2: Connect an AI client
|
|
135
|
+
|
|
136
|
+
Add this to your MCP client configuration:
|
|
137
|
+
|
|
138
|
+
**Claude Desktop** (`claude_desktop_config.json`):
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"mcpServers": {
|
|
143
|
+
"api-logic-pentest": {
|
|
144
|
+
"command": "uv",
|
|
145
|
+
"args": ["run", "app.py"],
|
|
146
|
+
"cwd": "/path/to/mcp-api-pentest"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Cursor** (`.cursor/mcp.json`):
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"mcpServers": {
|
|
157
|
+
"api-logic-pentest": {
|
|
158
|
+
"command": "uv",
|
|
159
|
+
"args": ["run", "app.py"],
|
|
160
|
+
"cwd": "/path/to/mcp-api-pentest"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Claude Code** (`~/.claude/mcp.json`):
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"mcpServers": {
|
|
171
|
+
"api-logic-pentest": {
|
|
172
|
+
"command": "uv",
|
|
173
|
+
"args": ["run", "app.py"],
|
|
174
|
+
"cwd": "/path/to/mcp-api-pentest"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Option 3: Sandbox mode (test locally)
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Starts a vulnerable mock API on port 8080
|
|
184
|
+
uv run mock_api.py
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The mock API includes 3 test users with tokens:
|
|
188
|
+
|
|
189
|
+
| User | Token | Role |
|
|
190
|
+
|------|-------|------|
|
|
191
|
+
| Admin | `admin_secret_token_2026` | admin |
|
|
192
|
+
| Victim | `user_victima_token_abc` | user |
|
|
193
|
+
| Attacker | `user_atacante_token_xyz` | user |
|
|
194
|
+
|
|
195
|
+
**Vulnerable endpoints** (intentionally broken for testing):
|
|
196
|
+
|
|
197
|
+
- `GET /api/v1/facturas/{id}` — IDOR (no ownership validation)
|
|
198
|
+
- `POST /api/v1/invoices` — creates invoice, captures ID for chained attacks
|
|
199
|
+
- `DELETE /api/v1/invoices/{id}` — deletes without ownership check
|
|
200
|
+
- `GET /api/v1/users/{id}/profile` — reads profile without ownership check
|
|
201
|
+
- `PUT /api/v1/users/{id}/profile` — mass assignment without ownership (escalate role to admin)
|
|
202
|
+
- `GET /api/v1/items` — pagination without bounds validation
|
|
203
|
+
- `POST /api/v1/items` — creates item for chained attacks
|
|
204
|
+
- `DELETE /api/v1/items/{id}` — deletes without ownership check
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Running Tests
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# Run all tests (102 tests, all passing)
|
|
212
|
+
uv run pytest
|
|
213
|
+
|
|
214
|
+
# Run with verbose output
|
|
215
|
+
uv run pytest -v
|
|
216
|
+
|
|
217
|
+
# Run tests for a specific module
|
|
218
|
+
uv run pytest mcp_api_logic_pentest/idor_detector/tests/
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Code quality checks:**
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Lint
|
|
225
|
+
uv run ruff check .
|
|
226
|
+
|
|
227
|
+
# Type checking
|
|
228
|
+
uv run mypy mcp_api_logic_pentest/ --ignore-missing-imports
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Available MCP Tools
|
|
234
|
+
|
|
235
|
+
The AI can use 11 tools to audit APIs:
|
|
236
|
+
|
|
237
|
+
| Tool | What it does |
|
|
238
|
+
|------|-------------|
|
|
239
|
+
| `parse_api_spec` | Reads an OpenAPI/Swagger file and extracts routes |
|
|
240
|
+
| `execute_security_request` | Sends HTTP requests with auth headers and rate limiting |
|
|
241
|
+
| `analyze_access_control` | Compares responses from two tokens to detect IDOR |
|
|
242
|
+
| `capture_context` | Stores a dynamic value (like a created ID) in memory |
|
|
243
|
+
| `get_context` | Retrieves a previously stored value |
|
|
244
|
+
| `list_context` | Lists all stored key-value pairs |
|
|
245
|
+
| `clear_context` | Resets the session cache |
|
|
246
|
+
| `extract_json_value` | Extracts a field from a JSON response using dot-notation |
|
|
247
|
+
| `save_security_finding` | Records a security finding to the audit report |
|
|
248
|
+
| `generate_report` | Returns the full Markdown audit report |
|
|
249
|
+
| `export_report_json` | Exports all findings as structured JSON |
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Architecture
|
|
254
|
+
|
|
255
|
+
This project follows a **Modular Monolith by Features** design.
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
mcp_api_logic_pentest/
|
|
259
|
+
├── config/ → Global settings and logger
|
|
260
|
+
├── shared/ → Reusable utilities (JSON truncation)
|
|
261
|
+
├── spec_analyzer/ → OpenAPI/Swagger file parsing
|
|
262
|
+
├── http_client/ → HTTP communication with auth providers
|
|
263
|
+
├── idor_detector/ → Multi-session authorization comparison
|
|
264
|
+
├── audit_context/ → In-memory state for chained attacks
|
|
265
|
+
├── report_generator/ → Security finding reports (Markdown + JSON)
|
|
266
|
+
├── orchestration/ → Cross-module attack flow coordinator
|
|
267
|
+
└── adapters/ → Entry points: MCP server and CLI
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Each module is self-contained with its own tests. New detection patterns (like Mass Assignment or Rate Limit testing) are added as new modules without touching existing code.
|
|
271
|
+
|
|
272
|
+
See `docs/adr/ADR-001-modular-monolith-by-features.md` for the full architecture decision.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Contributing
|
|
277
|
+
|
|
278
|
+
1. Create a branch from `integration/master`
|
|
279
|
+
2. Write your changes **plus tests** (we follow RED/GREEN/REFACTOR)
|
|
280
|
+
3. Push — CI runs lint, type check, and tests automatically
|
|
281
|
+
4. When CI passes, the merge happens automatically
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
MIT
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# mcp-api-pentest
|
|
2
|
+
|
|
3
|
+
An MCP server that lets AI assistants (Claude Desktop, Cursor, Claude Code) perform automated security audits on your APIs. It detects **BOLA/IDOR** vulnerabilities — the #1 risk in the OWASP API Top 10 — where one user can access another user's data.
|
|
4
|
+
|
|
5
|
+
> Think of it as giving your AI the ability to act like a penetration tester, running requests with different user tokens and comparing the results to find broken authorization logic.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Quickstart in 3 minutes
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 1. Clone and install
|
|
13
|
+
git clone https://github.com/josenieto/mcp-api-pentest
|
|
14
|
+
cd mcp-api-pentest
|
|
15
|
+
uv sync
|
|
16
|
+
|
|
17
|
+
# 2. Start the mock API (a vulnerable API for safe testing)
|
|
18
|
+
uv run mock_api.py
|
|
19
|
+
|
|
20
|
+
# 3. Start the MCP server
|
|
21
|
+
uv run app.py
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
That's it. The server is now running and waiting for an AI client to connect.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## What it does
|
|
29
|
+
|
|
30
|
+
The project acts as a bridge between an AI and your API:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
AI (Claude/Cursor) ←→ MCP Server ←→ API Target
|
|
34
|
+
|
|
|
35
|
+
Generates REPORTE_PENTEST.md
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Example attack flow the AI can run:**
|
|
39
|
+
|
|
40
|
+
1. **Create** an invoice with Token A → `POST /api/v1/invoices`
|
|
41
|
+
2. **Read** the same invoice with Token B → `GET /api/v1/invoices/42`
|
|
42
|
+
3. **Detect** the IDOR → both tokens return 200 OK with 94% similar content
|
|
43
|
+
4. **Save** the finding → "BOLA/IDOR in invoices endpoint — CRITICAL"
|
|
44
|
+
5. **Generate** a report → `REPORTE_PENTEST.md`
|
|
45
|
+
|
|
46
|
+
All of this happens without writing a single line of code — the AI drives the audit through MCP tools.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
- **IDOR detection**: Compares API responses with privileged vs unprivileged tokens
|
|
53
|
+
- **Chained attacks**: Create a resource, capture its ID, then attack it with a different user
|
|
54
|
+
- **Multi-session state**: Cache dynamic values across requests for complex attack flows
|
|
55
|
+
- **Smart truncation**: Handles massive JSON responses without flooding the AI's context window
|
|
56
|
+
- **Rate limiting**: Passive delays to avoid being blocked by WAFs
|
|
57
|
+
- **Markdown reports**: Automatic generation of security audit reports with evidence
|
|
58
|
+
- **Mock API sandbox**: 7 intentionally vulnerable endpoints for safe testing
|
|
59
|
+
- **CLI entry point**: Run from the terminal with `mcp-api-pentest --target https://api.example.com`
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
### From source (recommended for now)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
git clone https://github.com/josenieto/mcp-api-pentest
|
|
69
|
+
cd mcp-api-pentest
|
|
70
|
+
uv sync
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Requirements
|
|
74
|
+
|
|
75
|
+
- Python 3.10 or newer
|
|
76
|
+
- [uv](https://github.com/astral-sh/uv) package manager
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## How to Use
|
|
81
|
+
|
|
82
|
+
### Option 1: CLI mode (terminal)
|
|
83
|
+
|
|
84
|
+
Start the MCP server directly:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uv run app.py
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
With options:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
mcp-api-pentest \
|
|
94
|
+
--swagger spec.json \
|
|
95
|
+
--target https://api.example.com \
|
|
96
|
+
--token-admin "admin123" \
|
|
97
|
+
--token-victim "victim456" \
|
|
98
|
+
--token-attacker "attacker789" \
|
|
99
|
+
--output report.md \
|
|
100
|
+
--delay 1.0
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Option 2: Connect an AI client
|
|
104
|
+
|
|
105
|
+
Add this to your MCP client configuration:
|
|
106
|
+
|
|
107
|
+
**Claude Desktop** (`claude_desktop_config.json`):
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"mcpServers": {
|
|
112
|
+
"api-logic-pentest": {
|
|
113
|
+
"command": "uv",
|
|
114
|
+
"args": ["run", "app.py"],
|
|
115
|
+
"cwd": "/path/to/mcp-api-pentest"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Cursor** (`.cursor/mcp.json`):
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"api-logic-pentest": {
|
|
127
|
+
"command": "uv",
|
|
128
|
+
"args": ["run", "app.py"],
|
|
129
|
+
"cwd": "/path/to/mcp-api-pentest"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Claude Code** (`~/.claude/mcp.json`):
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"mcpServers": {
|
|
140
|
+
"api-logic-pentest": {
|
|
141
|
+
"command": "uv",
|
|
142
|
+
"args": ["run", "app.py"],
|
|
143
|
+
"cwd": "/path/to/mcp-api-pentest"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Option 3: Sandbox mode (test locally)
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Starts a vulnerable mock API on port 8080
|
|
153
|
+
uv run mock_api.py
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The mock API includes 3 test users with tokens:
|
|
157
|
+
|
|
158
|
+
| User | Token | Role |
|
|
159
|
+
|------|-------|------|
|
|
160
|
+
| Admin | `admin_secret_token_2026` | admin |
|
|
161
|
+
| Victim | `user_victima_token_abc` | user |
|
|
162
|
+
| Attacker | `user_atacante_token_xyz` | user |
|
|
163
|
+
|
|
164
|
+
**Vulnerable endpoints** (intentionally broken for testing):
|
|
165
|
+
|
|
166
|
+
- `GET /api/v1/facturas/{id}` — IDOR (no ownership validation)
|
|
167
|
+
- `POST /api/v1/invoices` — creates invoice, captures ID for chained attacks
|
|
168
|
+
- `DELETE /api/v1/invoices/{id}` — deletes without ownership check
|
|
169
|
+
- `GET /api/v1/users/{id}/profile` — reads profile without ownership check
|
|
170
|
+
- `PUT /api/v1/users/{id}/profile` — mass assignment without ownership (escalate role to admin)
|
|
171
|
+
- `GET /api/v1/items` — pagination without bounds validation
|
|
172
|
+
- `POST /api/v1/items` — creates item for chained attacks
|
|
173
|
+
- `DELETE /api/v1/items/{id}` — deletes without ownership check
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Running Tests
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Run all tests (102 tests, all passing)
|
|
181
|
+
uv run pytest
|
|
182
|
+
|
|
183
|
+
# Run with verbose output
|
|
184
|
+
uv run pytest -v
|
|
185
|
+
|
|
186
|
+
# Run tests for a specific module
|
|
187
|
+
uv run pytest mcp_api_logic_pentest/idor_detector/tests/
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Code quality checks:**
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Lint
|
|
194
|
+
uv run ruff check .
|
|
195
|
+
|
|
196
|
+
# Type checking
|
|
197
|
+
uv run mypy mcp_api_logic_pentest/ --ignore-missing-imports
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Available MCP Tools
|
|
203
|
+
|
|
204
|
+
The AI can use 11 tools to audit APIs:
|
|
205
|
+
|
|
206
|
+
| Tool | What it does |
|
|
207
|
+
|------|-------------|
|
|
208
|
+
| `parse_api_spec` | Reads an OpenAPI/Swagger file and extracts routes |
|
|
209
|
+
| `execute_security_request` | Sends HTTP requests with auth headers and rate limiting |
|
|
210
|
+
| `analyze_access_control` | Compares responses from two tokens to detect IDOR |
|
|
211
|
+
| `capture_context` | Stores a dynamic value (like a created ID) in memory |
|
|
212
|
+
| `get_context` | Retrieves a previously stored value |
|
|
213
|
+
| `list_context` | Lists all stored key-value pairs |
|
|
214
|
+
| `clear_context` | Resets the session cache |
|
|
215
|
+
| `extract_json_value` | Extracts a field from a JSON response using dot-notation |
|
|
216
|
+
| `save_security_finding` | Records a security finding to the audit report |
|
|
217
|
+
| `generate_report` | Returns the full Markdown audit report |
|
|
218
|
+
| `export_report_json` | Exports all findings as structured JSON |
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Architecture
|
|
223
|
+
|
|
224
|
+
This project follows a **Modular Monolith by Features** design.
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
mcp_api_logic_pentest/
|
|
228
|
+
├── config/ → Global settings and logger
|
|
229
|
+
├── shared/ → Reusable utilities (JSON truncation)
|
|
230
|
+
├── spec_analyzer/ → OpenAPI/Swagger file parsing
|
|
231
|
+
├── http_client/ → HTTP communication with auth providers
|
|
232
|
+
├── idor_detector/ → Multi-session authorization comparison
|
|
233
|
+
├── audit_context/ → In-memory state for chained attacks
|
|
234
|
+
├── report_generator/ → Security finding reports (Markdown + JSON)
|
|
235
|
+
├── orchestration/ → Cross-module attack flow coordinator
|
|
236
|
+
└── adapters/ → Entry points: MCP server and CLI
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Each module is self-contained with its own tests. New detection patterns (like Mass Assignment or Rate Limit testing) are added as new modules without touching existing code.
|
|
240
|
+
|
|
241
|
+
See `docs/adr/ADR-001-modular-monolith-by-features.md` for the full architecture decision.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Contributing
|
|
246
|
+
|
|
247
|
+
1. Create a branch from `integration/master`
|
|
248
|
+
2. Write your changes **plus tests** (we follow RED/GREEN/REFACTOR)
|
|
249
|
+
3. Push — CI runs lint, type check, and tests automatically
|
|
250
|
+
4. When CI passes, the merge happens automatically
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
MIT
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""CLI entry point for mcp-api-logic-pentest."""
|
|
2
|
+
import argparse
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
7
|
+
parser = argparse.ArgumentParser(
|
|
8
|
+
prog="mcp-api-pentest",
|
|
9
|
+
description="MCP server for autonomous API logic penetration testing",
|
|
10
|
+
)
|
|
11
|
+
parser.add_argument(
|
|
12
|
+
"--swagger", "-s",
|
|
13
|
+
help="Path to OpenAPI/Swagger spec file (JSON or YAML)",
|
|
14
|
+
)
|
|
15
|
+
parser.add_argument(
|
|
16
|
+
"--target", "-t",
|
|
17
|
+
help="Base URL of the API to audit",
|
|
18
|
+
)
|
|
19
|
+
parser.add_argument(
|
|
20
|
+
"--output", "-o",
|
|
21
|
+
default="REPORTE_PENTEST.md",
|
|
22
|
+
help="Output report path (default: REPORTE_PENTEST.md)",
|
|
23
|
+
)
|
|
24
|
+
parser.add_argument(
|
|
25
|
+
"--delay",
|
|
26
|
+
type=float,
|
|
27
|
+
default=0.5,
|
|
28
|
+
help="Delay in seconds between requests (default: 0.5)",
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"--token-admin",
|
|
32
|
+
help="Admin-level authentication token for multi-session audits",
|
|
33
|
+
)
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
"--token-victim",
|
|
36
|
+
help="Victim-level authentication token for multi-session audits",
|
|
37
|
+
)
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"--token-attacker",
|
|
40
|
+
help="Attacker-level authentication token for multi-session audits",
|
|
41
|
+
)
|
|
42
|
+
parser.add_argument(
|
|
43
|
+
"--config",
|
|
44
|
+
help="Path to YAML configuration file",
|
|
45
|
+
)
|
|
46
|
+
parser.add_argument(
|
|
47
|
+
"--mock",
|
|
48
|
+
action="store_true",
|
|
49
|
+
help="Launch the mock API sandbox instead of the MCP server",
|
|
50
|
+
)
|
|
51
|
+
return parser
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def main() -> None:
|
|
55
|
+
args = build_parser().parse_args()
|
|
56
|
+
|
|
57
|
+
if args.mock:
|
|
58
|
+
print("Starting mock API sandbox...")
|
|
59
|
+
import subprocess
|
|
60
|
+
subprocess.run([sys.executable, "mock_api.py"])
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
print("Starting MCP API Logic Pentest server...")
|
|
64
|
+
from mcp_api_logic_pentest.adapters.mcp_server import mcp
|
|
65
|
+
mcp.run()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from fastmcp import FastMCP
|
|
2
|
+
|
|
3
|
+
from mcp_api_logic_pentest.audit_context.attack_context import (
|
|
4
|
+
capture_context,
|
|
5
|
+
clear_context,
|
|
6
|
+
extract_json_value,
|
|
7
|
+
get_context,
|
|
8
|
+
list_context,
|
|
9
|
+
)
|
|
10
|
+
from mcp_api_logic_pentest.http_client.http_client import execute_security_request
|
|
11
|
+
from mcp_api_logic_pentest.idor_detector.access_analyzer import analyze_access_control
|
|
12
|
+
from mcp_api_logic_pentest.report_generator.reporter import (
|
|
13
|
+
export_report_json,
|
|
14
|
+
generate_report,
|
|
15
|
+
save_security_finding,
|
|
16
|
+
)
|
|
17
|
+
from mcp_api_logic_pentest.spec_analyzer.spec_parser import parse_api_spec
|
|
18
|
+
|
|
19
|
+
mcp = FastMCP("mcp-api-logic-pentest")
|
|
20
|
+
|
|
21
|
+
# ---------------------------------------------------------------------------
|
|
22
|
+
# Fase 1 + 4: HTTP client and spec parsing
|
|
23
|
+
# ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
mcp.tool()(parse_api_spec)
|
|
26
|
+
mcp.tool()(execute_security_request)
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
# Fase 2: Multi-session IDOR detection
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
mcp.tool()(analyze_access_control)
|
|
33
|
+
|
|
34
|
+
# ---------------------------------------------------------------------------
|
|
35
|
+
# Fase 3: State management for chained attacks
|
|
36
|
+
# ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
mcp.tool()(capture_context)
|
|
39
|
+
mcp.tool()(get_context)
|
|
40
|
+
mcp.tool()(list_context)
|
|
41
|
+
mcp.tool()(clear_context)
|
|
42
|
+
mcp.tool()(extract_json_value)
|
|
43
|
+
|
|
44
|
+
# ---------------------------------------------------------------------------
|
|
45
|
+
# Fase 5b: Report generation
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
mcp.tool()(save_security_finding)
|
|
49
|
+
mcp.tool()(generate_report)
|
|
50
|
+
mcp.tool()(export_report_json)
|