Burp Suite’s headless mode is a game-changer for integrating automated security testing into your CI/CD pipeline, but getting it right involves understanding a few key architectural pieces. The most surprising thing is that headless Burp doesn’t run scans in the way you might expect; it orchestrates them, relying on separate components for the actual crawling and scanning work.
Let’s see it in action. Imagine you have a basic CI job that needs to kick off a Burp scan against a staging environment.
stages:
- security_scan
burp_scan:
stage: security_scan
image: ubuntu:22.04 # Or a custom image with Burp Enterprise installed
script:
- echo "Starting Burp Enterprise headless scan..."
# Assuming BURP_API_KEY and BURP_ENT_URL are set as CI/CD variables
- apt-get update && apt-get install -y curl # Ensure curl is available
- |
curl -s -k -X POST "$BURP_ENT_URL/api/v1/scans" \
-H "Authorization: ApiKey $BURP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"scan_type": "crawl_and_audit",
"target": {
"urls": ["https://your-staging-app.com"],
"scope": {
"type": "inclusive",
"entries": [
{"url": "https://your-staging-app.com", "include": true}
]
}
},
"configuration": {
"throttle": {
"requests_per_second": 20
},
"insertion_point_detection": {
"enabled": true
},
"audit_optimization": {
"enabled": true
}
}
}' \
> scan_request.json
- SCAN_ID=$(jq -r '.scan_id' scan_request.json)
- echo "Scan initiated with ID: $SCAN_ID"
- |
# Poll for scan completion
STATUS="running"
while [ "$STATUS" != "completed" ] && [ "$STATUS" != "failed" ]; do
sleep 30
echo "Polling scan status for ID: $SCAN_ID..."
curl -s -k -X GET "$BURP_ENT_URL/api/v1/scans/$SCAN_ID" \
-H "Authorization: ApiKey $BURP_API_KEY" \
-H "Content-Type: application/json" \
> scan_status.json
STATUS=$(jq -r '.status' scan_status.json)
echo "Current status: $STATUS"
done
- |
if [ "$STATUS" == "completed" ]; then
echo "Scan completed successfully. Fetching report..."
curl -s -k -X GET "$BURP_ENT_URL/api/v1/scans/$SCAN_ID/report?report_format=json" \
-H "Authorization: ApiKey $BURP_API_KEY" \
-H "Content-Type: application/octet-stream" \
--output scan_report.json
# Process scan_report.json here, e.g., check for critical vulnerabilities
echo "Scan report generated."
else
echo "Scan failed. Check Burp Enterprise logs for details."
exit 1
fi
- echo "Burp Suite headless scan finished."
variables:
BURP_ENT_URL: "https://burp-enterprise.yourcompany.com" # Replace with your Burp Enterprise URL
BURP_API_KEY: "your-api-key-here" # Replace with your Burp Enterprise API Key
In this example, we’re using curl to interact with the Burp Enterprise REST API. The POST request initiates a new scan, specifying the target URL, the scope of the scan, and some basic configuration like throttling. The scan_type is set to "crawl_and_audit", which tells Burp to first discover the application’s attack surface and then perform active vulnerability checks. The subsequent GET requests poll the API for the scan’s status until it’s completed or failed. Finally, if successful, the report is downloaded.
The core problem Burp Suite Enterprise solves in this context is providing a centralized, scalable platform for security testing that can be managed and integrated into development workflows. Instead of individual developers running manual scans or managing disparate Burp Pro instances, Enterprise offers a single pane of glass for scheduling, executing, and reporting on scans across an organization. It handles the complexities of distributed scanning, resource management, and vulnerability aggregation.
The key levers you control are primarily within the API payload for scan creation. The scan_type can be adjusted (e.g., "crawl_only", "audit_only", or "crawl_and_audit"). The target object is crucial for defining what gets scanned; you can specify single URLs, use scope to include or exclude specific parts of an application, and even define custom crawl_strategies or event_triggers. Within configuration, you can fine-tune throttle settings to avoid overwhelming your application, enable or disable insertion_point_detection for more precise testing, and configure audit_optimization to prioritize certain checks. You can also set browser_config for authenticated scans or scans requiring specific browser behaviors.
The one thing most people don’t realize about how Burp Enterprise orchestrates scans is that it doesn’t perform the network requests itself. When you initiate a scan via the API, you’re telling the Burp Enterprise controller to assign the scan task to one or more Burp collaborator agents. These agents, which are separate Java processes running Burp Enterprise, are the ones that actually send HTTP requests to your target application, perform the crawling, and execute the audit checks. The controller then aggregates the findings from these agents and presents them in the UI and reports.
Once you have a reliable headless scan running, the next logical step is to integrate sophisticated reporting and analysis, perhaps by triggering a separate job that parses the JSON report for specific findings or integrates with a vulnerability management platform.