CSRF attacks are often used to compromise the data and features of a web application.
Principles, impacts, possible exploitations, we present in this article an overview of the CSRF vulnerability as well as security best practices and measures to implement to prevent the risks of attacks.
What is a CSRF vulnerability?
A CSRF vulnerability (Cross-Site Request Forgery) is a flaw that allows an attacker to abuse a user, a web browser and a server at the same time. The principle is quite simple. The objective of the attack is to force an authenticated user on a website or web application to perform specific actions without his knowledge.
This is done by corrupting the relationship between a web browser and a server, which is theoretically designed to prevent different web sites and applications from interfering with each other.
In a successful attack, a CSRF vulnerability can allow an attacker to force the change of a password and/or other personal information, and then retrieve sensitive data, etc. if the victim is a user with standard rights. If the victim has an administrator account, a CSRF attack can compromise the entire web application.
In general, when a feature is vulnerable to CSRF attacks, attackers seek to trick users into loading a malicious page.
This page with malicious code will send requests through a user’s browser as if it were a legitimate user action, allowing the attacker to perform actions such as changing the password and/or other personal information or changing the user’s personal settings and configurations on the vulnerable platform.
The impact of a successful CSRF attack can therefore be quite severe. Attackers often rely on social engineering techniques (e.g., phishing, usually by sending a link by email, which aims to redirect a user to a malicious site) to increase the chances of success.
Finally, one last clarification: CSRF attacks generally target modification requests (password and others) and not data theft, as attackers have no way of seeing the response to the forged request.
What are the requirements for a CSRF attack?
To carry out a successful CSRF attack, some requirements must be met:
- Authentication must be based solely on cookies. The triggering of the attack involves one or more HTTP requests and the application relies solely on cookies to authenticate the user.
- All request parameters must be predictable. The requests contain parameters whose values the attacker can determine or guess.
- The target application must contain interesting and/or critical functionalities for an attacker. Several cases are possible: functionality linked to high levels of rights, actions that will modify user-specified data, etc.
How to prevent CSRF attacks?
CSRF attacks are relatively simple to mitigate. CSRF attacks are relatively simple to counter. To do so, two security measures can be applied: implementing CSRF tokens or using the SameSite attribute on cookies.
Implementing CSRF token to prevent attacks
To protect against CSRF attacks, a common security measure is the implementation of CSRF tokens.
CSRF tokens are unique values randomly generated on the server side and sent to the client. Since these values are unique for each request, they enhance the security of an application by making it difficult (if not impossible) for an attacker to guess them and thus exploit a CSRF vulnerability.
Some frameworks, such as Django (Python) and Laravel (PHP) counts with middlewares to protect against CSRF attacks, which is activated by default.
Using the SameSite attribute on cookies to counter CSRF attacks
SameSite is an attribute that an application can insert on cookies. Indeed, when this attribute is placed on session cookies, they will not be sent to the server if the request does not come from the application’s domain.
The application receiving the request will not be able to link the request to any user and therefore will not process it. In theory, this provides total protection against CSRF attacks.
However, the SameSite attribute does not take subdomains into account. Thus, a user with control of a subdomain could compromise the application via a CSRF attack. For example, it would be possible to attack the “vaadata.com” platform from the “evil.vaadata.com” subdomain.
To avoid this security gap, the public suffixes list was created for browsers to change their SameSite validation behaviour.
Let’s take a closer look at how the SameSite attribute works:
The application instructs the user’s browser to create cookies via a “Set-Cookie” header. For instance, if we are dealing with a PHP/Laravel application, it is very likely that we will have a header value similar to this:
The Set-Cookie header allows several flags to improve the security of the user’s cookies: SameSite, Expires, Domain…
SameSite can be used with different values: Strict and Lax. When the attribute is set to “Strict” (SameSite=Strict), it means that the user’s browser will never send cookies along cross-site requests. The cookie is only sent for requests originated from the same domain and subdomains.
Set-Cookie: PHPSESSID=VxTGA2T1T0kE; Max-Age=43200; Secure; HttpOnly; SameSite=Strict
If the “Lax” attribute is set (SameSite=Lax), the client’s browser will be instructed to send cookies only over GET requests that can cause top-level navigation. This configuration grants that clients will still have access to your website’s resources if the cross-site interaction is intended.
Set-Cookie: PHPSESSID=VxTGA2T1T0kE; Max-Age=43200; Secure; HttpOnly; SameSite=Lax
Explicitly defining attributes for SameSite cookies improves security against CSRF attacks, as it prevents the browser from sending cross-site requests that include session cookies.
For more information on the principle and implementation of the Samesite attribute, you can refer to our dedicated article: Protecting against CSRF attacks with the SameSite cookie attribute.
How modern browsers counter CSRF attacks?
The first CSRF attacks were observed as early as 2000. At that time, protection measures were still rudimentary. Since then, the situation has changed.
Recent modifications in early 2020 were applied by major browsers such as Mozilla Firefox and Google Chrome, consisting in setting the cookies default attribute for “SameSite=Lax” every time it is not set by the web application. This has considerably reduced the number of CSRF attacks and that’s one of the reasons why it is not listed anymore in the OWASP Top Ten since the 2017 edition.
Another important thing to mention regarding Chrome browser is that it will allow POST requests on SameSite=Lax if the cookie has been set not more than 120 seconds ago. This intervention (“Lax+POST”) will be removed in the future.
In other words, Chrome will make an exception for cookies set without a SameSite attribute less than 2 minutes ago. Such cookies will also be sent with non-idempotent (e.g. POST) top-level cross-site requests despite normal SameSite=Lax cookies requiring top-level cross-site requests to have a safe (e.g. GET) HTTP method. This can potentially open a little gap for CSRF attacks, even though they will depend on social engineering a bit more.
In summary, CSRF (Cross-Site Request Forgery) is a type of attack on web applications and its main characteristic is to trick an authenticated user to perform an unwanted action. A successful CSRF attack depends on a weak authentication mechanism that relies solely on cookies to handle user sessions. Moving toward security by default, modern browsers are now applying some stricter cookies policies while some frameworks such as Django (Python) and Laravel (PHP) contain anti-CSRF mechanisms. Two main protections can be implemented against the CSRF vulnerability. The first relies on the cookie attributes, and the second is based on the implementation of CSRF tokens in the web application, that are unpredictable and managed only on the server-side. For an enhanced security, we recommend applying both techniques.