BurpSense bridges the gap between security testing in Burp Suite and your development environment in VS Code. The core idea is simple: instead of constantly switching between tools to cross-reference vulnerabilities with source code, you can map Burp's findings directly to the lines where issues occur. This gives you inline diagnostics, full advisory details and a persistent record of what needs attention.
If you've done web application security testing, you've probably experienced the friction of correlating Burp Suite findings with actual source code. You find an SQL injection, note the URL and parameter, then hunt through your codebase to figure out where that endpoint lives. Then you need to remember which file and line to fix, or worse, communicate this to someone else on your team who wasn't sitting next to you during testing.
Burp Suite does have a built-in API integration feature, but if you've tried using it, you know it's... let's say "minimalist".
The extension eliminates most of this friction. The Burp bridge exposes scan results through a clean local API and the VS Code extension consumes them in real-time. You get a live view of all findings and you can annotate specific lines of code with issues. These annotations persist in your workspace, so you can pick up where you left off without losing context.
The project has two components:
The Burp bridge is a Java extension that runs inside Burp Suite. It starts an HTTP server on localhost (default port 1337) and exposes your scan results through a REST API. It also maintains WebSocket connections to push updates when new issues appear or existing ones get removed. The bridge applies your filters (severity, confidence, scope) server-side, so only relevant issues get sent to clients.
The VS Code extension connects to this bridge and displays issues in a dedicated tree view. You can browse, search, and filter findings, then map them to specific lines in your source files. Mapped issues appear as diagnostics in the Problems panel, and clicking on one opens a detailed advisory with full HTTP request/response data. When you refactor code and lines move around, the extension attempts to track those changes and adjust mappings automatically.
Communication happens over HTTP for queries and WebSocket for real-time updates. The protocol is differential - after the initial sync, the bridge only sends what's changed (new issues, removed issues) rather than the entire dataset each time.
Burp Bridge:
- Burp Suite with Montoya API support (
2025.12or later) - Java 21 or higher
- Maven 3.6+ (for building from source)
VS Code Extension:
- VS Code 1.108.1 or higher
- Node.js 18.0.0 or higher (for building from source)
Start by building the bridge:
cd burp-bridge
mvn clean packageThis produces target/burpsense-bridge-*.jar. Load it in Burp Suite through the Extensions tab (click "Add" and select the JAR). After loading, you'll see a new "BurpSense Bridge Settings" tab appear.
Generate an API token using the "Generate New Key" button and copy it somewhere safe. Then click "Start Server" to begin listening. By default, the server binds to 127.0.0.1:1337, but you can change this in the settings panel if needed.
The bridge requires Burp Suite with the new Montoya API support.
You can install from VSCode Marketplace, Open VSX Registry, a packaged VSIX or run from source:
From VSIX:
cd vscode-extension
npm install
npm run compile
npx vsce packageThis creates burpsense-*.vsix. In VS Code, go to the Extensions view (Ctrl+Shift+X), click the "..." menu, and select "Install from VSIX".
From source (for development):
cd vscode-extension
npm install
npm run compileThen press F5 in VS Code to launch the Extension Development Host with the extension loaded and debugger attached.
After installing both components, run BurpSense: Set API Token from the command palette in VS Code and paste the token you generated in Burp. If everything is working, you should see BurpSense: Connected [X issues] in the status bar at the bottom of your editor. If it says "Disconnected", click the status bar for troubleshooting options.
First-time users: The extension shows a welcome panel on first launch with guided setup steps. You can also access the interactive walkthrough anytime via
Command Palette>Get Started with BurpSense.
The BurpSense view appears in the activity bar (the shield icon on the left side). Opening it shows a tree of issues organized by severity. Each issue displays its name, confidence level, and affected URL. The tree uses lazy loading, so it stays responsive even when you have hundreds of findings.
You can filter issues in several ways:
- Text search (searches names, URLs and issue IDs)
- Minimum severity (high, medium, low, information)
- Minimum confidence (certain, firm, tentative)
- Scope filter (show only in-scope issues)
The toolbar icons let you adjust these filters on the fly. There's also a "quick filter" menu that applies common presets like "high severity only" or "in-scope high and medium".
To map an issue to a line of code:
- Open the file and position your cursor on the relevant line
- Right-click and select
BurpSense: Map Burp Issue to this Line
- Choose the issue from the dropdown
The mapping gets saved to .burpsense/mappings.json in your workspace. This file can be committed to version control so team members see the same annotations.
Mapped issues appear in two places: the Problems panel (with appropriate severity icons) and directly in the editor as squiggly underlines. Click any diagnostic to open a detailed advisory showing the full issue description, remediation advice, and HTTP traffic if available.
When mapping, the extension analyzes your code context and suggests relevant issues. For example, if the line contains SQL keywords like SELECT or WHERE, it prioritizes SQL injection issues. This works for common patterns like file operations, authentication code, XSS-prone templates, and API endpoints.
When you refactor code, lines move around. BurpSense tries to keep mappings accurate by checking whether the text you originally mapped still exists nearby. When you edit a file with mappings, the extension:
- Checks if the exact text still appears on the mapped line
- If not, searches within +/- 20 lines for similar content (>80% match)
- Calculates similarity using character-level comparison with position weighting
- Updates the line number if it finds a good match
This works well for typical refactoring like adding functions or moving code blocks. It won't track cases where you completely rewrite the vulnerable code, but that's intentional - if the code changed that much, the original issue may no longer apply and you should verify it manually.
The extension can notify you when it adjusts mappings, though you can disable these notifications in settings if they're distracting.
Remove a single mapping by right-clicking the line and selecting BurpSense: Remove Mapping from this Line. To remove all mappings for a particular issue, hover over it in the tree view and click the trashbin icon. For bulk removal, use BurpSense: Remove multiple Mappings from the command palette.
The mappings file (.burpsense/mappings.json) is workspace-specific and can be committed to your repository. This means when a teammate clones the project and connects their own VS Code to a shared Burp Project, they'll see the same annotations you created. They'll need their own bridge API token, but the mappings themselves are just file paths and line numbers with issue IDs.
You can also export mappings to a standalone JSON file and import them in a different workspace if needed with dedicated commands.
Settings live in VS Code preferences under the "BurpSense" section:
{
"burpsense.bridgeIp": "127.0.0.1",
"burpsense.bridgePort": 1337,
"burpsense.inScopeOnly": true,
"burpsense.minSeverity": "INFORMATION",
"burpsense.minConfidence": "TENTATIVE",
"burpsense.showDriftNotifications": true,
"burpsense.confirmMappingDeletion": true,
"burpsense.autoCleanOrphanedMappings": false,
"burpsense.logLevel": "info"
}The IP and port should match where your bridge is listening. If you're running Burp on a different machine, adjust accordingly. The extension will reconnect automatically when these settings change.
Filter settings (severity, confidence, scope) apply server-side, which means the bridge only sends issues matching your criteria. Changing filters triggers a refetch, so there might be a brief delay while the new filtered set loads.
Drift notifications can be disabled if you find them noisy. The extension will still adjust mappings, just without notifying you.
Auto-clean orphaned mappings, when enabled, removes mappings for files that get deleted. This is disabled by default because you might temporarily remove files during refactoring and want the mappings to persist.
The logLevel setting controls logging verbosity. Set to error for minimal logs, warn for warnings only, info for normal operation, or debug for detailed troubleshooting output.
The Burp bridge exposes the following REST endpoints:
GET /health
Health check endpoint. Returns {"status":"ok"} when the server is running.
Response:
{"status":"ok"}GET /issues
Fetches all issues matching current filter criteria (severity, confidence, scope).
Headers:
Authorization: Bearer <token>
Response:
[
{
"id": "unique-issue-id",
"name": "SQL injection",
"severity": "HIGH",
"confidence": "CERTAIN",
"host": "example.com",
"path": "/api/users",
...
}
]POST /issues
Differential sync endpoint. Send known issue IDs to receive only changes since last fetch.
Headers:
Authorization: Bearer <token>Content-Type: application/json
Body:
{
"knownIds": ["id1", "id2", "id3"]
}Response:
{
"newIssues": [...],
"removedIds": ["id2"]
}GET /issues/{id}
Fetches a single issue by ID with full details including HTTP messages.
Headers:
Authorization: Bearer <token>
Response: 200 OK or 404 Not Found
GET /ws
WebSocket endpoint for real-time issue updates. Server broadcasts "refresh" message when issue count changes.
Headers:
Upgrade: websocketAuthorization: Bearer <token>
The bridge includes several security hardening measures:
- Rate Limiting: Fixed-window rate limiter protects against brute force attacks on the API token. Default: 100 requests per 60-second window. Rate limit headers (
X-RateLimit-Limit,X-RateLimit-Remaining) are included in responses. - CORS: Cross-Origin Resource Sharing middleware with
localhost/127.0.0.1defaults. This prevents unauthorized web pages from accessing the bridge API. - Constant-time token comparison: Authentication uses constant-time comparison to prevent timing attacks on API tokens.
- Localhost binding: By default, the server only listens on
127.0.0.1, preventing external network access. Change this setting with caution.
The extension uses a hybrid push/pull model. On initial load, it fetches all issues via GET /issues. Subsequent requests to POST /issues include the IDs of issues the client already knows about, and the bridge responds with:
{
"newIssues": [...],
"removedIds": [...]
}This differential sync significantly reduces network traffic during active scanning sessions where issues frequently appear and disappear.
WebSocket connections handle real-time updates. The bridge monitors its issue list every 2 seconds and broadcasts a refresh message when the count changes. Clients respond by fetching an incremental update.
Issues are cached locally with a 30 second TTL. After expiration, the tree view fetches fresh data the next time you expand a node. This avoids hammering the bridge with requests while keeping the display reasonably current.
The cache has two levels:
- Issue-level cache (raw scan data)
- Grouped data cache (tree nodes organized by severity/name)
When an incremental update arrives, both caches are invalidated, but the tree doesn't refetch unless something actually changed. This keeps the UI responsive even during heavy scanning activity.
The initial load with several hundred issues can take a few seconds while the tree builds its internal structure. After that, navigation is fast because the tree uses lazy loading - child nodes aren't created until you expand their parent.
The extension processes incremental updates synchronously, which means if you have a large removal event (like changing filters to exclude 500 issues), there might be a noticeable pause. This is a trade-off for keeping the sync logic simple.
If you manually disconnect using the status bar, the extension won't fetch data for any operation, including opening issue details. This is intentional - when you're disconnected, you're working with stale cache only. Reconnecting re-enables all fetches.
When the cache expires (after 30 seconds), the extension doesn't immediately refetch. It waits until you next interact with the tree view. This is by design to avoid background fetches when you're not actively looking at the extension.
With 1000+ issues, the tree can feel sluggish. This is partly because VS Code's tree view API isn't optimized for that many items, and partly because the grouping logic has to sort and organize everything. Consider using stricter filters to reduce the working set.
If the Burp bridge restarts, the WebSocket takes a few seconds to reconnect. During this window, you won't receive real-time updates, though the extension continues working with cached data. Once the connection re-establishes, you'll get an incremental sync of anything that changed.
The mappings file is plain JSON and gets rewritten entirely on every change. This means if two people edit mappings simultaneously, the last write wins. Git can handle this in most cases, but be aware that mappings don't merge intelligently across branches.
Work through these in order:
- Is Burp Suite running?
- Is the bridge extension loaded? (Check Extensions tab in Burp)
- Is the server started? (Check Bridge Settings tab)
- Does your API token match between Burp and VS Code?
- Is something blocking set port? (Firewall, another service)
The status bar is clickable and opens a quick actions menu with diagnostics. Check the VS Code output panel (BurpSense: Show Logs command) for connection logs.
First, verify the issues actually exist in Burp's sitemap. Then check your filter settings - you might have the minimum severity set too high, or scope filtering enabled when the issues aren't in scope. Try clicking the refresh button in the tree view toolbar. If that doesn't work, check the output panel for errors.
Make sure the file path in the mappings matches your workspace structure exactly. The extension uses paths relative to the workspace root, so if your workspace root isn't what you expect, mappings might not resolve. Check .burpsense/mappings.json to see what paths are stored, and verify they match your actual file locations.
The similarity algorithm is conservative (70% match threshold), but false positives can still happen if you have very similar code repeated in nearby lines. If drift detection is causing problems, you can turn off notifications in settings. The extension will still adjust mappings, but you can check the Problems panel to verify they're still pointing to the right code.
To build from source, you need Maven for the bridge and Node.js for the extension.
cd burp-bridge
mvn clean packageOutput is in target/burpsense-bridge-*.jar. Load this in Burp's Extensions tab.
To run tests:
# Unit tests only
mvn test
# Unit + integration tests
mvn verify
# Only integration tests
mvn verify -DskipUnitTests
# With coverage report
mvn clean verify
The project maintains 70% line coverage. Tests use JUnit 5, Mockito and REST Assured.
cd vscode-extension
npm install
npm run compileFor active development, use npm run watch to recompile automatically when you change files. Press F5 in VS Code to launch the Extension Development Host with debugger attached.
Code quality:
# Type check
npm run check-types
# Lint
npm run lint
# Watch mode (type check + compile)
npm run watch
Issues and pull requests are welcome. For major changes, please open an issue first to discuss the approach. When reporting bugs, include VS Code and Burp Suite versions, extension version, and logs from both components (VS Code output panel and Burp's extension output tab).
burpsense/
├── burp-bridge/
│ └── src/main/java/com/arqsz/burpsense/
│ ├── api/ # HTTP endpoints and handlers
│ │ ├── handler/ # Health, issues, single issue endpoints
│ │ └── middleware/ # Auth, CORS, rate limiting
│ ├── service/ # Issue filtering and management
│ ├── config/ # Settings persistence and key storage
│ ├── constants/ # Server, security, and UI constants
│ ├── ui/ # Bridge settings panel and components
│ └── util/ # JSON mapping and validation
└── vscode-extension/
└── src/
├── commands/ # Command palette handlers
├── events/ # Connection state change events
├── providers/ # Tree view, diagnostics, code actions
├── services/ # Connection, caching, mapping, smart suggestions
├── ui/ # Webview panels for advisories and welcome
└── extension.ts # Entry point and activation
Built using Burp Suite's Montoya API, Undertow for HTTP/WebSocket serving, native fetch and ws for client networking, and sanitize-html for XSS protection in advisory panels.







