Restrict sending custom request headers to allowed hosts
Problem
DAST sends user configured custom request headers with every request, regardless of the host. This can cause the following issues:
- A request that was previously a simple CORS request becomes a preflighted request
- Scans are slower due to the extra preflighted HTTP request (one per external resource request)
- If the external host rejects the preflight request due to the additional header, it's likely the user's scan will fail (missing JavaScript, CSS, etc)
- If the external host accepts the preflight request despite the additional header, the the request header is sent to the external host. This can be a security issue, depending on what was configured in the request headers.
This only affects requests made by a browser.
Proposal
Limit custom request headers to only be sent on DAST_BROWSER_ALLOWED_HOSTS. This is a breaking change.
This applies to the CI/CD variables DAST_REQUEST_HEADERS_BASE64, DAST_REQUEST_HEADER and DAST_REQUEST_HEADERS.
Proof that tokens may be leaked
The following redacted log was taken from a customer scan:
2022-10-06T05:30:16.000 TRC CHROM event received {"method":"Network.requestWillBeSent","params":
{"requestId":"240.6","loaderId":"4E1105698FC8652047FB127FDC470C3B","documentURL":"<redacted>","request":
{"url":"https://use.fontawesome.com/releases/v6.2.0/css/all.css","method":"GET","headers":{"Authorization":"Bearer <secret-token>",...
Reference
From customer issue, see internal Slack thread.
Example
A user has a target website, that loads bootstrap JavaScript from an external CDN. A simple CORS request is made, to get the JavaScript. This is a GET HTTP request, where the response is status 200, the resource body contains the JavaScript and there is a Access-Control-Allow-Origin response header.
Suppose the user adds a custom authorization token header, DAST_REQUEST_HEADERS: "Authorization: Bearer secret.token". The following network requests show that an extra request is made, a preflight CORS request. In this case, maxcdn.bootstrapcdn.com rejects the preflight request, therefore the JavaScript is unable to load.
Implementation plan
-
Remove the call to Network.setExtraHTTPHeaders (DevTools), as this indiscriminately adds headers to every request made by the current browser tab (https://gitlab.com/gitlab-org/security-products/analyzers/browserker/-/merge_requests/881/) -
Store the custom headers and allowed hosts as new fields on the browser.Tab(seeTab.Init/setCustomHeaders) (https://gitlab.com/gitlab-org/security-products/analyzers/browserker/-/merge_requests/881/) -
The DevTools event Fetch.requestPaused(DevTools) is used to intercept all requests and responses. When a request is continued, add the custom headers toContinueRequestWithParamsif the request host is an allowed host. The headers/allowed hosts can be retrieved from the tab. (part 1: https://gitlab.com/gitlab-org/security-products/analyzers/browserker/-/merge_requests/881/, part 2: https://gitlab.com/gitlab-org/security-products/analyzers/browserker/-/merge_requests/885) -
Using an integration test, verify that extra headers are sent, but only to allowed hosts -
TestCookiesAreRecordedWhenNavigationIsExecutedis a good example of such a test. More than one HTTP server could be created, so that there is more than one host. The second server could load a CSS file from the first server, emulating the problem.
-

