0%
False
Go Back

CSRF Attack Prevention

Utilising CSRF Tokens to prevent Cross Site Request Foregery

Posted by Zain Ahmed on August 16, 2025

Introduction

During the development of my company’s service Lightwire Hosting, we had come to deal with the challenge of the potential of Cross Site Request Forgery attacks. This is an attack method that utilises requests using the trust a site has in a user’s browser. An example of this would be sending a POST request using the browser to another site that only checks the user’s current session cookie. As a result, any request sent from another page to said site would process as if the user themselves were performing the request, and as this can occur in the background, the user may themselves be completely unaware of this happening.

Mitigation

The solution to mitigate this vulnerability is to check the user’s intent to perform such action when a request is being validated. This can occur in the form of CSRF Tokens. In my site, I have chosen the method of storing a CSRF token to the user’s sessionstore serverside, and then sending the CSRF token within the HTML loaded in the webpage. When the user submits the form or other state-changing request, the CSRF token is submitted alongside the remainder of the payload, and the server validates the token to the one it has stored server side. My implementation saves only one token per user, so in the event that the user opens a different form or page with buttons leading to state-changes, the previous token is overwritten serverside. Also known as per-page generation, this prevents any other changes being committed without the user’s knowledge.

Implementation

I have implemented this into Flask applications, using basic libraries.
All we need is session in the flask library, and the secrets library. You can adapt the rest to your own application. As I do not use any library for forms, I will also import request from flask, in addition to render_template.

PYTHON

from flask import session, render_template, request import session ... @app.route("/order") def order(): token = secrets.token_urlsafe(10) session['CSRF'] = token # Add any other logic you need return render_template("order.html", CSRF=token)

With this the CSRF token is now saved in the serverside session, and now we wait for the user to complete the action

PYTHON

@app.route('/order/checkout', methods=['POST']) def checkout(): if session.get('CSRF') is None: return "Invalid CSRF Token", 400 if request.form.get('CSRF') != session.get("CSRF"): return "CSRF Token does not match", 400 # Continute processing logic here, session is validated.

Now that the user's session has been validated, we can proceed with any state-changes that needed to occur. This method should be used in-conjuction with standard authentication protocols, a CSRF token does not replace that. By changing the token on each page, we are further able to ensure that the token is only alive as needed. For a more complex implementation, one could use a database and store the user's identifier alongside the CSRF token instead of saving it directly in the serverside sessionstore, which could allow you the ability to add specific expiry to the token.