Usually, an application is vulnerable to CSRF if the interaction between the client and the server is built in an insecure way. For example, a client and a server interact via GET requests. These requests are made via accessing the URL with parameters. The URL may look like this:
The browser makes a GET request to the server, passing it the name of the method and the method's arguments. This example deletes a report ('ActionName=DeleteReport'). This already looks strange: GET requests shouldn't delete anything.
The report name is passed in the 'ReportName' parameter. If an attacker knows the report name, they can enter any suitable value.
The request executed at this URL deletes the report. The attacker doesn't even need an access to the victim's computer or account. Although, it looks like the victim deleted the report.
To perform an attack, a hacker generates a URL, an access to which starts malicious actions.
The attack may be performed via HTML markup. This means the attack can be performed implicitly when a page is loading. For example, an attacker can insert any URL in the 'src' attribute of the 'img' tag. While the page loads, a browser tries to get an image and sends a request to this URL.
So, the attacker creates their page with a zero-size 'img' element and uses the following request as the image URL:
Next, they apply social engineering and encourages a victim to load malicious markup — open a web page or an email made in HTML. A request is executed implicitly, and the victim doesn't notice anything suspicious.
This way of performing CSRF is called a GET scenario. The attack is possible if the website developers violated the standard — they didn't follow the instructions about the idempotency of GET requests. You shouldn't use GET requests for state-changing actions.
var req = new XMLHttpRequest();
var url = 'domainname/DoAction';
var args = 'ActionName=DeleteReport&ReportName=ThatReport';
req.open('POST', url, false);
window.onload = sendRequest;
The attacker, using social engineering, encourages the victim to open a malicious page. The consequences of opening the page are similar to those for the GET script. The request to the vulnerable server will be implicit and the victim will not notice it being sent.
The value of the 'method' attribute is responsible for the HTTP method. Then the markup can look like this:
<form action="domainname/DoAction" method="post">
<input type="hidden" name="ActionName" value="DeleteReport"/>
<input type="hidden" name="ReportName" value="ThatReport"/>
<input type="submit" value="Some clickbaiting text"/>
The attacker, having information about names of actions and reports, can substitute any suitable value. The values are stored in hidden input fields. The request payload will be generated from these values.
When a victim clicks on the form submission button, a POST request to the URL is generated. This POST request has a payload of the hidden fields described above.
Again, the attacker uses social engineering to encourage the victim to go to the page. Besides opening a malicious page, the script requires actions on it — clicking the form submission button.
Don't use GET requests for state-changing actions. Besides GET and POST, the HTTP standard describes many methods designed for different purposes: PUT, DELETE, etc. For example, to delete something, use the HTTP 'DELETE' method. Thus, the first thing to do against CSRF is to correctly implement the API. It can be REST API, for example.
The article from the OWASP website offers several patterns to solve the CSRF problems. They all have the requirement of a verification token. When a user proceeds to a vulnerable element, for example, to a form to fill out, the server returns a verification token along with the content. The number of tokens and their location (in markup, cookies, etc.) depend on the security pattern used. The choice of pattern depends on how the vulnerable element is loaded (static page, AJAX, etc.) and the characteristics of the server (stateful or stateless). When a user performs actions that send data to the server, the verification token is sent along with them. If there's no token in the incoming request or it's incorrect, the server won't process such request.
Date: Jan 12 2024
Author: Gleb Aslamov
Date: Dec 07 2023
Author: Anastasiya Vorobeva
Date: Dec 05 2023
Author: Anastasiya Vorobeva
Date: Nov 21 2023
Author: Andrey Karpov
Date: Oct 24 2023
Author: Uliana Grishina