Infrastructure at your Service

Pascal Brand

Apache JMeter and Cross-Site Request Forgery (CSRF) token management

Introduction

In Nowadays web technologies a common defensive mechanism against Cross-Site Request Forgery (CSRF) attacks is to use a synchronizer token. This token might be unique for each request and thus it blocks us from using the recorded JMeter test session off the shelf.

This blog will describe how this CSRF feature can be handled in JMeter.

How to implement this feature

The solution is to identify and extract the CSRF token from the response data or header depending how is it has been set.
The site I was doing the Load test using JMeter is using a cookie to set the CSRF Token and adds a X-CSRFToken header to the following HTTP requests.

The HTTP Response header contains something like:

Set-Cookie: csrftoken=sTrKh7qgnuKtuNTkbwlyCv45W2sqOaiY; expires=Sun, 21-Jan-2017 11:34:43 GMT; Max-Age=31449600; Path=/

To extract the CSRF token value from the HTTP Response header, add a Regular Expression Extractor Post Processor globally.
This way if the token value is reset to a new value somehow, it will be dynamically updated in the following response.

Now configure it as follows:

Apply to: Main sample only
Field to check: Response Headers
Reference Name: CSRF_TOKEN
Regular Expression: Set-Cookie: csrftoken=(.+?);
Template: $1$

Get the Response Cookie via the Regular Expression Extractor

DynCSRF_Regular_Expression

It is always better to have a user variable attached to the extracted value to be kept during the complete load test run.
select user defined variables and add a new variable with the same name as the reference name declared above in the regular expression Extractor.

DynCSRF_variable

The next step is to analyse each HTTP Request recorded in the scenario to replace the hard coded value for the X_CSRFToken header with the variable set by the Post Processor as shown below:

DynCSRF_HTTP_Header

To avoid having to check every request HTTP Header Manager as displayed above which can take some time and might introduce errors, a pre-processor can be used that checks the headers
and replace automatically the X_CSRFToekn hard coded value with the variable set by the post processor task. This kind of pre-processor can be time consuming and should be as simplest as possible. Thus I decided to not check if the X_CSRFToken exist in the request header and just call the remove header attribute and add the X_CSRFToken one to all requests. This worked fine for the site I was working on.

The pre-processor code used was the following:

import org.apache.jmeter.protocol.http.control.Header;

sampler.getHeaderManager().removeHeaderNamed("X-CSRFToken");
newValue=vars.get("csrfToken");
sampler.getHeaderManager().add(new Header("X-CSRFToken",newValue));

DynCSRF_BeasnShell

 

2 Comments

  • Candy Tellez says:

    Hi Pascal!

    First of all thank you for the post. Right now we are having problems with X_CSRFToken, we followed all the steps you mentioned in the post, but it is still failing :(. Looking at the results we saw something weird, we are not sure that this can be the problem but might be. After the variable passes the pre procesor the X_CSRFToken comes out encoded, is there any way it can show the value not encoded? because when we check the value before it passes re pre processor it is not encoded.
    Thank you very much for your valuable help and we are looking forward to your response.

     
    • Pascal Brand says:

      Hello Candy,

      Can you confirm the configuration you are having is the same ? I mean the csrftoken is set using a cookie and has to be injected back in the HTTP/S requests headers ?
      The preprocessor doesn’t encode the token. All it does is get the csrfToken value from the variable and set in in the subsequent HTTP/S requests headers.
      Make sure there is no typos in the variable name, neither in the cookie name.

      Hope this helps,
      Pascal

       

Leave a Reply


5 × eight =

Pascal Brand
Pascal Brand

Consultant & Middleware Technology Leader