Bypass client-side generated HTTP security headers

Every now and then when doing a security test on a web application I have to deal with client-side generated HTTP headers that are there for security reasons. These headers can cause problems during a security test. Fortunately, they can easily be bypassed using Burp Suite.

HTTP "security" header

Let me explain the concept of a HTTP security header using a header with the name Auth-code, that is being added by the web browser itself (i.e. think about JavaScript running in the browser). The header value which is calculated involves the contents of the HTTP request message. This can be as simple as calculating a hash over the body within a HTTP POST request message. 

The web application will check the value of the Auth-code every time a HTTP request is received. If the value received does not match the expected result, the web application will deny the HTTP request and most likely send back an error message to the web browser. E.g.: "Invalid input provided".

False sense of security

These kind of security mechanisms does not add any real security to the web application. An adversary has full control on what happens on the client (i.e. web browser) and therefore what will be send to the web application. Because a header such as Auth-code is calculated and added by the client itself, an adversary also has the ability to make sure the Auth-code always has the correct value.

Security checks should always be performed on the web application server and not be fully depended on code that is running within the browser.

Example of exploitation

Imagine having a web application that relies for an important part of its security on a custom header called Auth-code. The value for the header is calculated and added to the HTTP request using JavaScript by the client itself. 

This web application has a webpage that shows user personal details such as name, address, email, etc. When accessing this webpage a user ID is provided within the parameter UserID, contained within the body of the HTTP request. Manipulating the user ID (e.g. by means of a proxy) will result in an error at the web application. After all the provided Auth-code will not match up with the expected value.

All we have to do to bypass the security check in the above case is making sure the Auth-code we sent will always match the content of the body within the HTTP request. Every time we manipulate a parameter this will require re-calculating the value for the Auth-code. Of course we first need to know how this value is being calculated and under which circumstances it is being used. Knowing that, we can make sure to always include the correct value.

When doing a security test it can be quite cumbersome if re-calculating the Auth-code value has to be done manually. Or simply not possible when you want to take advantage of the active scanner within Burp. We need a way that we can automate this process. We can achieve this by writing our own extension for Burp Suite.

How to bypass using Burp Suite

Burp Suite allows expanding its functionality with extensions. Those can be written in Java, Python or Ruby. I choose to write it in Python. This extension will make sure that for every HTTP request being send the custom security header (e.g. Auth-code) will match the expected value. It will work for all requests being send through Burp Suite: Repeater, Intruder, Active scanner, etc.

Burp extension

On my GitHub page you will find a Burp extension that serves as a template for bypassing a custom security header. Within the Python code I have added comments that should help you in customising the code to fit the web application you are testing.

https://github.com/marcusbakker/Burp-Suite-Extensions