Protecting Your Web Apps From CSRF

Protecting Your Web Apps From CSRF

In the last article Secure Web App Configuration For Developers , we discussed how to use HTTP Headers to secure web apps from many common attacks such as XSS(Cross Site Scripting), Clickjacking, and CRSF (Cross-Site Request Forgery). We have another technique we can use to add another layer of defense against CSRF.

What is CSRF?

Cross-Site Request Forgery is when an attacker is able to make authenticated request on the users behalf. This abuses the trust between the browser and the web server. CSRF vulnerabilities are practically dangerous as it can impact the confidentiality, integrity, and availability of users data.

How CSRF Works

CSRF attacks can be executed in a multitude of ways, but for simplicity let's go over a scenario, where we are a using a web app for banking. Given the typical flow of how most web applications are used, when first visit the banking website we are presented with a login page.

We enter our username and password

When we press submit, an HTTP POST request is made to the server where it will do it's authentication process. If we supplied the correct credentials, the web server will create a session, and send back an HTTP Response that contains a Set-Cookie header instructing the browser to store either a sessionID or auth_token.

Upon a successful login we have an authenticated session, we are then directed to our account page. Where we can view our account details, and click a link to transfer money to other users.

Let's say we want to transfer some money to another user.

Place in the user and amount we want to transfer.

The POST Request is made and could look like this.

On the server-side, it will process this request see if the session is authenticated using the cookie and transfer the money.

Implementing CSRF Against POST Endpoints

For a successful CSRF we need a couple things.

  1. An authenticated session.

  2. A known endpoint for the targeted functionality.

  3. The proper HTTP method to the endpoint.

We know from this example we need to make a HTTP Post Request, by submitting a form (application/x-form-urlencoded). Usually it is easier to do a CSRF in HTTP GET request because we can distribute the link via phishing. We can still implement a CSRF against a POST Endpoint but may take a little work.

To accomplish this we need to set up a form that tricks the user into indicating a POST request on our behalf. To accomplish this the form we use should use the hidden attribute of the fields expected for the request.

When we use hidden attributes these fields will not seen by the user, but will be added to the submission of the form. We can see it below

Notice how the Cookie with the auth_token is added to the request. This is vital to a CSRF attack, because this gives us access to the authenticated session.

The Perfect Storm

To deliver this attack we can also use a phishing email, but the link will point towards fake website we set-up. With a fake form that a user will fill out but will not be actually submitted to the endpoint.

Given a scenario, a user just logged into the bank account, and has there email open. They receive an email from us. That is highly convincing, say a survey about the banks services.

When they press take survey, it goes to a fake site we created with a survey that has a fake form.

Above is the form that is presented to the user, but when they submit it, none of the responses will actually be sent. The html and script to make it happen is as follows

The script removes the name attributes from the radio inputs, so it will not transmit the data on submit, only the to user and amount inputs expected for the request. Thus making a transfer to our fake account.

Protecting Against CSRF

Now that we understand how a CSRF Attack works, we will go over two ways to protect against it.

  • Anti-CSRF Tokens

  • Re-authorization

Anti-CSRF Tokens

What if there was a way to ensure that, when a request is made, it adheres to the flow of logic of our application. There indeed is, and we can use Anti-CSRF tokens.

  1. During rendering of the page we add the Anti-CSRF Token.

  2. We add it to the request.

  3. On the server we check if the token is present, if it is not the request is illegitimate.

Let's walk through this in code

We see the code to add the Anti-CSRF Token, and we can see the output in the browser

When the form is submitted the token will be added, along with to user and amount in the request.

Now on the server we validate the token.

If not valid we stop processing the request.

Re-Authorization

Re-authorization effectively mitigates CSRF attacks by requiring an additional verification step that an attacker cannot bypass without the user's credentials. This mechanism ensures that only legitimate users can perform sensitive actions, thereby protecting the integrity and security of user accounts and transactions.

It maybe easier to add Re-Authorization instead of adding Anti-CSRF tokens depending on the needs of your application.

Summary

Understanding how a successful CSRF Attack is implemented, can allow us to use security mechanisms to protect against it. The two covered are Anti-CSRF Tokens which can also be implemented not only on form submissions, but also API Request as well. Re-Authorization maybe easier to implement as your application should already have an authentication and authorization process. This can ensure the integrity of a session, and ensure our application is not being used in unintended ways.

Did you find this article valuable?

Support Jeremiah Liscum by becoming a sponsor. Any amount is appreciated!