# CSRF attack prevention

Before explaining how to combat **CSRF** *(Cross Site Request Forgery)*, a quick explanation of the technique behind it is in order.

A cross site request forgery relies on a user visiting a malicious site, shortly after they have logged into a genuine site, and whilst they still have a session cookie active with the genuine site.

By making the user's browser send malicious requests directly back to the genuine site, the malicious site can exploit the fact that the user is already logged in, to effectuate such things as placing orders in the user's name, sending emails using the user's credentials or posting comments to other users in what may well be a trusted user's name. The list of exploits is endless and only really subject to the vulnerabilities of the site being attacked.

Ways to make the user visit the malicious site whilst still being logged into the genuine site includes phishing, posting of links in comments on the genuine site, or even just "trial and error" by posting links on sites that may also be frequented by users of the genuine site.

The limitation of the CSRF attack is that it is always "**blind**". The attacker cannot see what the application responds with, or what the current state of the session is; due to restrictions imposed by browser security models that say that a request from one server *(domain)* cannot be sent to another.

## CSRF defense techniques <a href="#toc492971228" id="toc492971228"></a>

How to best protect your site against CSRF attacks depends on **how it was written**. Generally speaking, most applications perform actions as a result of an HTML form being posted to the site. Some sites also respond with actions to a GET request

For example: "<http://www.mysite.com/delete.jsp?orderToDelete=12345>"

This example will focus on protecting applications that use a form **POST**. This is done by adding a **hidden field** to every form presented by the application. This hidden field contains a random value that is unique to the specific session of the user. We will require that this field is always present on a form POST, making it virtually impossible for a malicious site to second guess what a valid POST request might look like.

The technique for protecting a site that uses GET requests is similar, simply requiring the addition of an **additional URL parameter** to every URL that takes parameters, instead of a hidden form field.

### Planning the rules <a href="#toc492971229" id="toc492971229"></a>

The first step in implementing our CSRF defense is to create a simple plan of action i.e. what do we intend to do, and how do we wish to go about doing it. It is a good idea to write this down in plain English and then use that text as a guide whilst designing the rule structure. In this case, the plan reads as follows:

1. If a POST request comes in whilst there is an **active session**, then make sure it has our hidden field, and that it is the hidden field we have generated for that session. If the field is not present, we should respond to the user with an HTTP Status code of ***403 (Forbidden)***.
2. Whenever a new page is provided by the application, make sure we add a large random number as the hidden field to every form presented by the application. The large random number we use should be generated once for the session and then be stored in it for easy reference and good performance.

That sounds easy enough; so, let's begin...

## Getting started <a href="#toc492971230" id="toc492971230"></a>

Create a new repository named "**CSRF Example**" and add a new rule set named "**CSRF**".

Filter out static content before it hits the core rules using a Name Splitter and Switch rule as shown:

![Static content filtering using Name Splitter and Switch rules](/files/QvoRCMT4X6FtOqKVM73c)

* The **Name Splitter** conveniently extracts the extension of the object being requested using the following properties:

<figure><img src="/files/NJfjoLcPzxRR4AcfrJPO" alt=""><figcaption><p>Name Splitter properties</p></figcaption></figure>

* The **Switch** rule operates on the EXT variable. By adding new chain points for each type of static content they are eliminated from reaching the rule set.

![Switch properties](/files/UoM6jO1Ej1HHxc6IJk0H)

As we are dealing with Web Applications, and we need to know information such as the method used (*POST/GET),* the first step is to add an HTTP Request Tracker rule from the HTTP group in the rules catalog to the CSRF rule set:

![HTTP Request Tracker added](/files/C9EDNIC3uYP9CzHxgtHO)

A good technique for rule writing is to start by determining the "flow" of events or pages that will subsequently have rules applied to them.

In our case we have two flows:

* The verification of the forms
* The addition of the form fields.

So, our next action is to add a Sequencer rule from the Flow group in the rules catalog:

![Sequencer rule added](/files/h1CrqdAeYoGIOeVETdxC)

### Implementing step 1 <a href="#toc492971231" id="toc492971231"></a>

Now, the first step in our written plan is to check if we are dealing with a **POST** request in the session, and if the form posted has our **hidden field**. The first part is very easy:

![HTTP Session Check with If Condition](/files/MlMFeXuP6O1zj78jEhDn)

Only the **If Condition** requires some properties:

<figure><img src="/files/Yi6RXuMQwNTMAEcTiv3i" alt=""><figcaption><p>If Condition properties</p></figcaption></figure>

The next step is simple. We need to look up the current hidden field from the session:

![HTTP Section Reader with If Condition rules](/files/i9yAWe7Qi3lWGu90bEou)

Once again, there are not many properties:

<figure><img src="/files/vi56Cz3HsEkQoKU2Pf8m" alt=""><figcaption><p>HTTP Session Reader properties</p></figcaption></figure>

<figure><img src="/files/DLipQSTZPLSiJNaAHRer" alt=""><figcaption><p>If Condition properties</p></figcaption></figure>

The variable names and values we have chosen are arbitrarily selected, although they should be meaningful and memorable.

In this example, we have decided that the hidden field is stored with a session key named "`CSRF.key`" and that the hidden field on all forms is named "`CSRF`". We could have chosen any names as long as we use them consistently when we add the field to the form and store the session key.

All that is left for the first step is to make sure that if the key doesn't match, then the user receives a 403 error.

![403 error flow](/files/SnfgmNZCrSp2K9bW9Wm9)

Once again, the properties are very simple:

<figure><img src="/files/3yYKV15ahTHEswSVhWFL" alt=""><figcaption><p>HTTP Response properties</p></figcaption></figure>

We use a Set Completed rule after the response, as once we have decided that the user should be rejected, there is no need to proceed with the rest of the rule set. Instead we simply terminate the flow.

### Implementing step 2 <a href="#toc492971232" id="toc492971232"></a>

We are now ready to implement the second part of the plan. The first step in doing so is getting the actual response from the server so that we can add the hidden field if we need to.

![2nd implementation in the Sequencer](/files/1unJrWwklT3M7g7VZPuO)

The HTTP Server Execute rule takes care of this, even if you are writing rules using a built in forwarding proxy.

Once again, the properties are very simple as we are just interested in the application response:

<figure><img src="/files/Epsnlg7toocgptJAjprh" alt=""><figcaption><p>HTTP Server Execute properties</p></figcaption></figure>

Once again, we need to check if a session is present, but after the HTTP Server Execute rule, as that rule may in fact result in a session being created:

![HTTP Session Check added](/files/83sIKwqpZBKIs566ILcz)

If there is a session, then we need to add our **unique CSRF key** to it. The first step in doing that is to see if we already have that key:

![HTTP Session Reader and If Condition to check if the key is blank](/files/euSaj9zQdrWdYZGcaG8b)

Once again, not many properties:

<figure><img src="/files/eWdGaOvzri3dAyICOFDX" alt=""><figcaption><p>HTTP Session Reader properties</p></figcaption></figure>

<figure><img src="/files/KqohjLUHJPqI5fKfrcY4" alt=""><figcaption><p>If Condition properties</p></figcaption></figure>

If we don’t have it, we need to create it, which is easy:

![Random Number and HTTP Session Writer to create and store a rando number](/files/200tPr8hpm1gNh3Gk9Zb)

The properties for these rules are as follows:

<figure><img src="/files/7m46d4jfxlJ5wMfoiiTc" alt=""><figcaption><p>Random Number properties</p></figcaption></figure>

<figure><img src="/files/dZ6gclDENvbfrLrWvfjJ" alt=""><figcaption><p>HTTP Session Writer properties</p></figcaption></figure>

The session key we use is the same "`CSRF.key`" that we used in [step 1](#toc492971231).

All that remains now is to add the field to the form and send the response back to the user.

Thankfully there is a dedicated rule that handles the first problem, the "**Insert Hidden Field**" rule.

<figure><img src="/files/lYNCWfZhL0ISUwUG3vH9" alt=""><figcaption><p>Insert hidden field rule added</p></figcaption></figure>

Note that we are handling various loose ends too: connecting a Session not found to the HTTP Response, and connecting the existing session key to the Insert Hidden Field rule.

The final properties that must be set are as follows:

<figure><img src="/files/ffnAtmObFP5JCpl6zZWJ" alt=""><figcaption><p>Insert hidden field properties</p></figcaption></figure>

<figure><img src="/files/O38Bift61g0TOG99JWMz" alt=""><figcaption><p>HTTP Response properties</p></figcaption></figure>

## Testing <a href="#toc492971233" id="toc492971233"></a>

Our rule set is now complete, and we are ready to test it. A good sample application for this test is the **Qwerty** application. Create a configuration for the test named "**CSRFTest**" and set it as follows:

<figure><img src="/files/uB70wpOp0ei8ZcNV90dP" alt=""><figcaption><p>General tab for CSRFTest configurations</p></figcaption></figure>

<figure><img src="/files/NgKLOfms4MUumFXQwPNq" alt=""><figcaption><p>Input source tab for CSRFTest configurations</p></figcaption></figure>

(Only relevant sections shown)

Once you have set up your configuration, **deploy it to the Qwerty demo server** and try testing it.

You will see in the Qwerty application, in the "**Set up 3rd Party Accounts**" page, that there is now a **CSRF hidden field** added to the page:

<figure><img src="/files/ahYQyBbJYEjiF0nCYTuL" alt=""><figcaption><p>CSRF hidden field</p></figcaption></figure>

Use the performance data to further verify that everything is working as you expected.

## Adding more protection <a href="#toc492971234" id="toc492971234"></a>

If you look further through the page source of the Qwerty application, you may also notice the following link:

<figure><img src="/files/F4wPwEGveie05riaBbDX" alt=""><figcaption><p>A link with to a GET request with params</p></figcaption></figure>

This is a classic case of a GET request that can be exploited using CSRF. In this basic case study, we only protect POST requests of forms. However, if your application also uses actions on GET request, you can fairly easily amend the rule set to also cover GET requests.

This involves manipulating any URL parameters in the pages that are used for actions.

You can do this using the **String Replacer** rule, especially if your application uses "`.jsp`" or "`.do`" or "`.aspx`" as URL identifiers for active content.

For example, you could replace "`.jsp?`" in every page with "`.jsp?CSRF=0123456789&`" and then check for the field on every URL that ends in "`.jsp`" and has **PARAMETER\_NAMES** *(from HTTP Request Tracker Rule)* not equal to blank. If you do that you will achieve the same result as the Insert Hidden Field rule does in this case study.

## Additional CSRF notes <a href="#toc492971235" id="toc492971235"></a>

The above example is based on implementing the CSRF problem **as a single rule set**.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tomorrowx.com/cap/guides/examples/csrf-attack-prevention.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
