Gurp: Automating Burp Suite Professional from the Command Line with Go
Hook
Most penetration testers spend thousands on Burp Suite Professional licenses but never touch its REST API—the feature that could automate 80% of their repetitive scanning work.
Context
Burp Suite has been the gold standard for web application security testing since 2003, but it's predominantly GUI-driven. For years, pentesters wanting automation had to resort to unwieldy solutions: writing custom Burp extensions in Java or Python, using undocumented APIs, or cobbling together brittle Selenium scripts to drive the UI. When PortSwigger introduced the official REST API in Burp Suite Professional v2.0.0beta, it opened the door to programmatic control, but interacting with REST endpoints directly from shell scripts or CI/CD pipelines remained cumbersome.
Gurp emerged as a purpose-built CLI wrapper around this REST API, written in Go for cross-platform compatibility and easy distribution. The tool targets a specific pain point: security engineers who want to trigger Burp scans from Jenkins jobs, orchestrate testing workflows from bash scripts, or integrate Burp into larger security automation frameworks without dealing with curl commands or HTTP client libraries. It's a thin but effective layer between your terminal and Burp's scanning engine.
Technical Insight
Gurp's architecture follows the classic CLI-as-API-client pattern. Written in Go, it leverages the language's excellent HTTP client libraries and straightforward binary compilation to create a single executable that can communicate with Burp Suite's REST API, which runs on localhost:1337 by default when Burp Professional is launched with API mode enabled.
The tool structures its commands around Burp's primary functional areas: scanning, proxy history, configuration, and project management. Under the hood, Gurp translates your CLI commands into appropriate HTTP requests to Burp's endpoints. For example, initiating a scan involves constructing a POST request to /v0.1/scan with the target URL and configuration options in the request body.
Here's a practical example of using Gurp to start an automated scan:
# Start Burp Suite Professional with REST API enabled
java -jar burpsuite_pro.jar --project-file=myproject.burp --headless \
--config-file=burp-config.json
# Use Gurp to initiate a crawl and audit scan
gurp scan --url https://target.example.com --scope-prefix https://target.example.com
# Check scan status
gurp scan --status <scan-id>
# Retrieve issues when complete
gurp issues --scan-id <scan-id> --severity high
The communication flow looks like this: Gurp receives your command-line arguments, parses them using Go's flag package or a CLI framework like Cobra, validates the inputs, constructs the appropriate JSON payload, and sends it to Burp's API endpoint. Burp processes the request, performs the security testing operations, and returns JSON responses that Gurp formats for terminal output.
One architectural strength is Gurp's handling of long-running scans. Since Burp scans can take minutes to hours, Gurp implements asynchronous operation tracking. When you start a scan, it returns immediately with a scan ID that you can use to poll for status updates or retrieve results later—critical for CI/CD integration where you might trigger a scan in one pipeline stage and collect results in another.
The Go implementation provides several practical advantages. First, cross-compilation is trivial: GOOS=linux go build produces a Linux binary; GOOS=windows go build creates a Windows executable. Second, Go's static linking means you can copy a single binary to any system without dependency hell. Third, Go's strong typing and error handling make the API client code robust against malformed responses or network issues.
Here's a conceptual example of how Gurp might structure an API call internally:
type ScanRequest struct {
URLs []string `json:"urls"`
ScopePrefix string `json:"scope_prefix,omitempty"`
ScanType string `json:"scan_type"`
}
func (c *Client) StartScan(req ScanRequest) (*ScanResponse, error) {
payload, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("marshaling request: %w", err)
}
resp, err := c.httpClient.Post(
c.baseURL + "/v0.1/scan",
"application/json",
bytes.NewBuffer(payload),
)
if err != nil {
return nil, fmt.Errorf("sending request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
}
var scanResp ScanResponse
if err := json.NewDecoder(resp.Body).Decode(&scanResp); err != nil {
return nil, fmt.Errorf("decoding response: %w", err)
}
return &scanResp, nil
}
This pattern—struct-based request/response models, explicit error handling, clean separation between API client logic and CLI interface—is idiomatic Go and makes Gurp maintainable and extensible. If Burp adds new API endpoints, adding support in Gurp means creating the appropriate structs and a method to handle the HTTP interaction.
For practical pentesting workflows, Gurp shines in scripted scenarios. Imagine running nightly security scans against staging environments. You could write a simple bash script that starts Burp headlessly, uses Gurp to configure scan settings, initiates scans against multiple endpoints, polls for completion, exports findings in JSON format, and posts results to Slack or JIRA. This workflow—impossible with GUI-only Burp—becomes straightforward with Gurp as the glue layer.
Gotcha
The first major limitation is the Burp Suite Professional requirement. Gurp is useless without it, and Burp Pro costs around $400/year per user. If you're evaluating security automation options and don't already have Burp licenses, this represents significant investment before you write a single line of automation code. The Community Edition lacks the REST API entirely, making Gurp incompatible.
Second, you're constrained by Burp's REST API surface area. Not all Burp functionality is exposed through the API. Advanced features like Burp Collaborator management, certain extension interactions, or fine-grained Intruder configurations may require GUI access or custom extensions. If Burp's API doesn't support something, Gurp can't bridge that gap—it's a wrapper, not a workaround. You'll also encounter version dependencies: Burp's API evolves across releases, and Gurp may lag behind or require updates to support newer API versions.
The relatively low adoption (56 GitHub stars) suggests limited battle-testing in diverse environments. You might encounter edge cases or bugs that haven't been reported or fixed. Documentation may be sparse compared to more popular tools, and community-contributed examples or Stack Overflow answers will be scarce. When troubleshooting issues, you're largely on your own or dependent on the maintainer's responsiveness. For production-critical security automation, this represents risk compared to more established tooling.
Verdict
Use Gurp if: you already have Burp Suite Professional licenses and want to integrate security scanning into CI/CD pipelines, automate repetitive pentest tasks from shell scripts, or orchestrate multi-tool security workflows where Burp is one component among many. It's particularly valuable for teams that prefer infrastructure-as-code approaches and want their security testing to be version-controlled, reproducible, and scriptable. The Go implementation makes deployment trivial across different environments.
Skip if: you don't have Burp Professional (the investment barrier is too high just for CLI access), you need to automate Burp features not exposed through the REST API, or you're looking for a standalone security scanner rather than a wrapper. Also skip if you're comfortable with curl and JSON manipulation—you might not need the abstraction layer Gurp provides. Consider OWASP ZAP with zap-cli instead if you want open-source tooling with no licensing costs, or evaluate whether Burp's REST API directly or purpose-built extensions better serve your automation needs.