ProfessionalCommunity Edition
Custom actions reference guide
-
Last updated: April 29, 2025
-
Read time: 6 Minutes
Custom actions are scripts that run directly in Burp Repeater to automate tasks and extract information during manual testing.
This page includes building block examples of custom actions. If you're new to custom actions, we recommend starting with our worked example to see a breakdown of a complete script. Once you're familiar with the basics, use this page as a reference to build your own.
Related pages
To view examples of custom actions that have been created by our researchers and the community, see our Bambdas GitHub repository - Custom actions.
On this page
API access
Five objects of the Montoya API are available to help you write custom action scripts:
HttpRequestResponse
- Represents the full HTTP request and response.RequestResponseSelection
- Represents selected portions of a request or response.MontoyaApi
- Provides access to Burp features.Utilities
- Provides access to the Montoya API helper functions.Logging
- Enables logging output to the Output panel in the Custom actions side panel.
Related pages
Step 1: Accessing request and response data
To work with a HTTP message, use the HttpRequestResponse
object to retrieve the request or response.
Retrieving the full request or response
You can access the entire HTTP request or response as follows:
// Get the full HTTP request
var request = requestResponse.request();
// Get the full HTTP response
var response = requestResponse.response();
Extracting specific parts of the message
If you only need to analyze a section of the message, you can retrieve specific parts of the request or response, such as the body or headers. For example:
// Get response body as a string
var responseBody = requestResponse.response().bodyToString();
// Get the value of a specific request header
var userAgent = requestResponse.request().headerValue("User-Agent");
Extracting user-selected content
If the user will select a specific section of the request or response when using the custom action, you can access the selection using RequestResponseSelection
:
// Get selected text from the response as a string
var selectedText = selection.responseSelection().contents().toString();
Step 2: Processing data
Once you've accessed the message, you can process and analyze the data in various ways, using the MontoyaApi
and Utilities
objects.
This section covers the following use cases:
Decoding data
To decode data in a request or response, you'll need to do the following:
Extract the relevant section of the message.
Use a regular expression or decoding logic to process the data.
Output the result.
The following example decodes any \uXXXX
Unicode escape sequences found in user-selected sections of a response and logs the decoded characters:
// Get selected text from the response as a string
var selectedResponseText = selection.responseSelection().contents().toString();
// Create a regex pattern to find \uXXXX Unicode escape sequences
var pattern = Pattern.compile("\\\\u([0-9a-fA-F]{4})");
// Match Unicode escape sequences in the selected text, extract the 4 hex digits, convert them to an integer, then to a character
var decodedText = pattern.matcher(selectedResponseText).replaceAll(match -> String.valueOf((char) Integer.parseInt(match.group(1), 16)));
// Log the decoded sequences
logging.logToOutput(decodedText);
Testing server responses to different inputs
To test how a server responds to different inputs, create custom actions that modify and send a request, then log the output from the response.
Note
You won't see the modified request in Repeater, as it's sent in the background.
To test server responses to different inputs:
Get the relevant section of the request.
Change, remove, or add elements of the request.
Resend the updated request using the
api()
object.Log the output from the response.
This example removes the Authorization
and Cookie
headers before resending the request, then logs the response status code:
// Get the original HTTP request
var request = requestResponse.request();
// Remove the "Authorization" and "Cookie" headers from the request
var modifiedRequest = request.withRemovedHeader("Authorization").withRemovedHeader("Cookie");
// Send the modified request and get the response
var response = api().http().sendRequest(modifiedRequest).response();
// Log the response status code
logging.logToOutput(response.statusCode());
This example changes the request path, sends the request, then logs the full response as a string:
// Add /../../ to the original request path
var modifiedRequest = requestResponse.request().withPath("/../../");
// Send the modified request and log the full response
logging.logToOutput(api().http().sendRequest(modifiedRequest).response().toString());
Fetching external data
You can make outbound HTTP requests to retrieve external data.
To fetch external data:
Set the URL to fetch data from.
Send the request using the
api()
object.Parse the response body to extract the data you need.
Output the result.
This example sends a GET
request to PortSwigger's research RSS feed and extracts the link to the latest article:
// Sets the URL to fetch data from
var apiURL = "https://portswigger.net/research/rss";
// Send a GET request and get the response body
var responseBody = api().http().sendRequest(HttpRequest.httpRequestFromUrl(apiURL)).response().bodyToString();
// Use string splitting to extract the first link from the first >item< in the RSS feed
var extractedData = responseBody.split(">item<")[1].split(">link<")[1].split("<")[0];
// Log the extracted link
logging.logToOutput(extractedData);
Step 3: Logging and using the data
You can extract, log, and forward the results of your custom action in any way that fits your workflow.
This section covers the following use cases:
Logging to the Output panel in the Custom actions side panel.
Sending data to other Burp tools. This is particularly useful when you want to inspect or manually edit a modified request.
Logging to output
You can log data to the Output panel in the Custom actions side panel using the logging()
object.
This example identifies and logs a hash code representing the HTTP response body content, and the number of lines in the response body:
// Get the response body as a string
var responseBody = requestResponse.response().bodyToString();
// Log a hash code representing the body content
logging.logToOutput(responseBody.hashCode());
// Split the response body by newline characters and log the number of lines
logging.logToOutput(responseBody.split("\n").length);
Logging data to a file
You can log data to an external file, for example a text file in your home directory.
To log data to a file:
Build the file path.
Extract and format the data you want to log.
Open the file in append mode to avoid overwriting existing content.
Handle any errors to avoid unexpected failures, for example if the file isn't found or there is an error while writing to the file.
This example logs the HTTP service (host, port, and protocol) from a request to output.txt
in the user's home directory. It then logs whether it succeeded or failed:
// Get the path to the user's home directory and append "output.text".
var filePath = System.getProperty("user.home") + File.separator + "output.txt";
// Get the HTTP service as a string
var line = requestResponse.httpService().toString();
// Open the file make sure it closes automatically afterward
try (FileWriter writer = new FileWriter(filePath, true)) {
// Append the HTTP service to the file
writer.write(line + "\n");
// Log a success message
logging.logToOutput("http service recorded.");
} catch (IOException e) {
// Log an error if writing fails
logging.logToError("Could not write to " + filePath, e);
}
Sending data to another Repeater tab or other Burp tools
You can send data to other Burp tools using the api()
object. This can be useful when:
You want to integrate your custom action into your testing workflow.
You want to inspect a modified request. Because modified requests are sent in the background, they aren't normally visible. Sending the modified request to another tool (or Repeater tab) lets you view it.
This example makes a request to fetch a CSRF token, and updates the original request with the token. It then sends the modified request to another Repeater tab:
// Send a request to retrieve the CSRF token
var reqResp = api.http().sendRequest(requestResponse.request().withPath("/user/csrf"));
// Update the original request with the extracted CSRF token from the response body
var req = requestResponse.request().withUpdatedHeader("CSRF", reqResp.response().body().toString());
// Send the updated request to Repeater
api.repeater().sendToRepeater(req);