CSRF: Cross-site Request Forgery
Author: HollyGraceful Published: 06 August 2021 Last Updated: 03 November 2022
Often abbreviated to CSRF and often pronounced as “Sea-Surf” is an attack against a Web Application that abuses an application’s trust in the user. An attacker’s aim is to cause a function to execute on the application using the user’s authentication credentials simply by causing the user’s browser to request that function in the normal way, but from a malicious site.
For example, a user navigates to a malicious site and this site in turn sends a request to the vulnerable function on the vulnerable web site. This is where “Cross-site” comes from, it is a malicious site sending a request to the vulnerable site.
A protection mechanism exists to prevent domains from messing with each other, known as Same-Origin Protection (SOP). This protection prevents one domain from processing responses from other domains and there-by generally prevents any malicious two-way interaction between websites. However, it only prevents the malicious application from processing the response, it does not prevent the victim application from receiving and processing a request. Some requests can cause damage without the requirement for a response.
Take the function for changing a user’s password. If an application has a change password function that is accessed in a way such as:
and the response is simply “Success” this could be abused by attackers for the purposes of account take-over. The attack would simply be that the victim navigates to a malicious site where that site sends the above GET request to the vulnerable web-server.
The attacker can place the payload on a malicious site with HTML such as:
<img src="http://vulnerable.example.com/myprofile?change-password=Password123" width=0 height=0>
The user’s web browser will by default pass along the user’s cookie-based access token to the victim website and as far as the site is concerned the user has changed their password. Allowing the attacker to simply navigate to vulnerable.example.com in their own browser and login using the password “Password123”.
There are two simple ways to fix this issue, either is generally sufficient independently. The first is for the application to check the “Referer” header in the HTTP request, if it’s not coming from a trusted site then the request should be denied.
The second way to fix this issue is to embedded in the page body a security token that is required for each function to execute, as the token is embedded in the page body an attacker would not be able to determine what this is as Same-Origin Policy blocks the attacker from reading responses!