A self-hosted tool for turning Burp Suite HTTP proxy exports into an interactive API coverage map. Upload an XML file, get a structured view of every endpoint — organized by host and path, with request/response inspection, per-endpoint notes, and a pannable mind map.
- Upload Burp Suite XML — drop the file exported from Proxy → HTTP History → Save Items
- Two views, one toggle
≡ List— collapsible tree grouped by host → path segment → endpoint⬡ Map— interactive horizontal mind map, drag to pan, zoom with+/−orCtrl+Wheel
- Filters — method (GET/POST/PUT/PATCH/DELETE/HEAD), status class (2xx/3xx/4xx/5xx), keyword search, interesting-only, unreviewed-only
- Per-endpoint detail panel — full decoded request & response, extracted parameters, notes field
- Mark endpoints — flag as ★ Interesting or ✓ Reviewed while working through the map
- Multi-project — create separate projects to keep different engagements isolated
- Deduplication — re-uploading the same file or an overlapping export skips duplicates (keyed by method + URL)
- Single container — React frontend, FastAPI backend, SQLite, and nginx all in one Docker image
git clone <repo>
cd burpmap
docker compose up -dOpen http://localhost:8080.
Data is stored in a named Docker volume (burpmap_data) and survives container restarts.
docker build -t burpmap .
docker run -d -p 8080:8080 -v burpmap_data:/data burpmap- Create a project — click
+ New Projectin the header and give it a name. - Export from Burp Suite — in the Proxy tab, select all items in HTTP History, right-click → Save Items → save as XML.
- Upload — click
Upload XMLin the header, choose your file, wait for the import summary. - Explore
- Use
≡ Listto navigate the tree and click an endpoint to open the detail panel. - Switch to
⬡ Mapfor the mind map. Drag the canvas to pan, use the zoom controls in the top-right corner, or holdCtrland scroll.
- Use
- Work through the map — mark endpoints as Interesting or Reviewed in the detail panel, add notes, review the raw request and response.
Uploads are idempotent. If you capture more traffic and re-export, uploading the new file only adds the previously unseen endpoints. The import result shows added vs skipped counts.
burpmap/
├── backend/
│ ├── main.py # FastAPI app, REST endpoints
│ ├── burp_parser.py # Burp XML → endpoint list
│ ├── models.py # SQLAlchemy models (Project, Endpoint)
│ ├── schemas.py # Pydantic schemas
│ ├── database.py # SQLite engine, session factory
│ └── requirements.txt
├── frontend/
│ └── src/
│ ├── App.jsx # Root layout, filter/view state
│ ├── components/
│ │ ├── CoverageTree.jsx # List view (collapsible tree)
│ │ ├── MindMapView.jsx # Map view (pannable mind map)
│ │ ├── DetailPanel.jsx # Request/response, notes, flags
│ │ ├── FilterPanel.jsx # Method/status/search filters
│ │ ├── Header.jsx # Project switcher, upload trigger
│ │ └── UploadModal.jsx # File upload dialog
│ └── services/api.js # Axios API client
├── Dockerfile # Multi-stage: Vite build → Python 3.11 + nginx
├── docker-compose.yml
├── nginx.conf
└── start.sh
Backend: FastAPI + SQLAlchemy + SQLite. No external database required.
Frontend: React 18, vanilla CSS-in-JS — no UI framework dependencies.
Container: Single image, single port (8080). nginx serves the built React app and proxies /api/* to uvicorn.
Interactive docs at /api/docs once the container is running.
| Method | Path | Description |
|---|---|---|
GET |
/api/projects |
List projects |
POST |
/api/projects |
Create project |
DELETE |
/api/projects/{id} |
Delete project and all its endpoints |
POST |
/api/projects/{id}/upload |
Upload Burp XML file |
GET |
/api/projects/{id}/endpoints |
List endpoints (filterable) |
GET |
/api/projects/{id}/endpoints/{eid} |
Get single endpoint with full request/response |
PUT |
/api/projects/{id}/endpoints/{eid} |
Update endpoint (notes, flags) |
GET |
/api/projects/{id}/stats |
Coverage stats (total, reviewed, by method) |
Endpoint query parameters: methods, statuses, search, interesting_only, unreviewed_only.
| Field | Type | Description |
|---|---|---|
url |
string | Full URL |
host |
string | Hostname |
port |
integer | Port |
protocol |
string | http or https |
method |
string | HTTP method |
path |
string | Path (without query string) |
status_code |
integer | HTTP response status |
mime_type |
string | Response MIME type |
response_length |
integer | Response body length in bytes |
request |
text | Decoded raw HTTP request |
response |
text | Decoded raw HTTP response |
param_names |
JSON | Extracted query/body parameter names |
is_interesting |
boolean | Manually flagged |
is_reviewed |
boolean | Manually marked reviewed |
notes |
text | Free-form notes |
BurpMap expects the Proxy → HTTP History → Save Items XML export. This is the <items>/<item> format, not the Burp Scanner findings export (<issues>/<issue>).
The parser:
- Strips the inline
<!DOCTYPE>block before parsing (required for Python's standard XML library) - Skips
OPTIONSrequests automatically - Decodes
base64="true"request and response fields - Extracts parameter names from query strings, JSON bodies, form-encoded bodies, and multipart form fields
| Environment variable | Default | Description |
|---|---|---|
DB_PATH |
/data/burpmap.db |
Path to the SQLite database file |
cd backend
pip install -r requirements.txt
uvicorn main:app --reload --port 8000cd frontend
npm install
npm run dev # proxies /api/* to localhost:8000 via vite.config.jsStart the backend on port 8000, then npm run dev in the frontend directory. The Vite dev server handles the proxy.
MIT