Simulate HTTP status 429 with OWASP ZAP
Why?
When developing and testing code for Spring Data Elasticsearch I often use the OWASP ZAP proxy to monitor the data that is sent to and returned from Elasticsearch.
I now had the situation that I needed to check how the library behaves when the server returns a code 429 (too many requests) status. Rather than trying to set up a test that tries to flood my local Elasticsearch instance, I decided to add a script to ZAP that automatically for a given percentage of requests returns that status.
Add the script to ZAP
After starting ZAP, got to the Scripts tab and right-click on the proxy entry to create a new script; give the script a name, choose the script engine and the template.
Replace the content from the template with the following code:
// The proxyRequest and proxyResponse functions will be called for all requests and responses made via ZAP,
// excluding some of the automated tools
// If they return 'false' then the corresponding request / response will be dropped.
// You can use msg.setForceIntercept(true) in either method to force a breakpoint
// Note that new proxy scripts will initially be disabled
// Right click the script in the Scripts tree and select "enable"
/**
* This function allows interaction with proxy requests (i.e.: outbound from the browser/client to the server).
*
* @param msg - the HTTP request being proxied. This is an HttpMessage object.
*/
function proxyRequest(msg) {
// Debugging can be done using println like this
print('proxyRequest called for url=' + msg.getRequestHeader().getURI().toString())
return true
}
/**
* This function allows interaction with proxy responses (i.e.: inbound from the server to the browser/client).
*
* @param msg - the HTTP response being proxied. This is an HttpMessage object.
*/
function proxyResponse(msg) {
// Debugging can be done using println like this
print('proxyResponse called for url=' + msg.getRequestHeader().getURI().toString())
if (Math.random() < 0.25) {
responseHeader = msg.getResponseHeader()
responseHeader.clear()
responseHeader.setVersion('HTTP/1.1')
responseHeader.setStatusCode(429)
responseHeader.setReasonPhrase('Too Many Requests')
msg.setResponseBody('')
}
return true
}
After that, use the context menu to save your script and enable it, otherwise it will not be used by ZAP:
And don’t forget to disable the script after the tests, otherwise ZAP will keep using it!