Cross-site Request Forgery (CSRF) is a malicious attack that exploits the permission of a trusted user on a website to execute an unauthorized command. Exploiting sites that trust trusted users by masquerading their requests is not very popular, but it is difficult to prevent and no less dangerous than other security vulnerabilities.
This article will briefly introduce the causes of CSRF and the ways to use it, and then provide some schemes for reference on how to avoid this kind of attack, hoping that the vast number of programmers can understand this kind of attack, so as to avoid their applications being used by others.
CSRF, also known as one-click Attack or Session riding, is sometimes abbreviated using XSRF.
[TOC]
This article will continue to be revised and updated, please refer to my GITHUB program ape growth plan project for the latest content, welcome Star, more exciting content please follow me.
What is CSRF?
Simply put, a CSRF attack is when an attacker uses the identity of the victim to send malicious requests in the name of the victim. Different from XSS (Cross-site Scripting), XSS is designed to obtain user identities, while attackers steal user identities (session/cookie), whereas CSRF uses users’ current identities to perform unauthorized operations.
CSRF attacks was discovered in 2001 at the earliest, as a result of its request from the user’s IP address, so in the web log server may not be able to detect whether the CSRF attacks, it is because of this kind of its concealment, for a long time has not been publicly reported, it was not until 2007 that the real attention by people.
CSRF can steal a victim’s identity and do whatever the victim has permission to do in a Web browser, which is a lot to think about.
- Sending fraudulent emails, messages on your behalf
- Use your account to buy goods
- Complete virtual currency transfers in your name
- Privacy disclosure
- .
Generation principle and use way
To complete a CSRF attack, the following conditions must be met:
- The victim has logged into the target site (your site) and has not logged out
- Victims intentionally or unintentionally visit pages or links posted by attackers
(The picture is from the Internet, the source is unknown, Baidu to)
The whole process looks something like this:
- User Xiaoming logs in to your website A, and A returns A session ID (stored using cookies).
- Xiaoming’s browser keeps the login state of website A. In fact, almost all websites do so. Generally, at least before the user closes the browser, the user’s session will not end
- The attacker xiaoqiang sends Ming a link to the address, which Ming opens to view the content of the web page
- When Xiao Ming opened this address, the page had automatically sent A request to website A. At this time, as website A did not quit, as long as the requested address is A, it will carry the cookie information of A, that is, the session between A and Xiao Ming will be used
- At this time, A website must not know that this request is actually sent on the forged web page of Xiaoqiang, but mistakenly thought that Xiaoming is to operate in this way, so that Xiaoqiang can arbitrarily change xiaoming’s information on A, to operate in the identity of Xiaoming on A website
Using the way
CSRF attack mainly includes two ways: one is based on GET request and the other is based on POST request.
The use of GET request is the simplest one, and the source of its hidden danger is mainly due to the development of the system when it does not follow the correct use of HTTP verbs. For a GET request, it should be read-only and not allow any changes to the content of the site.
However, this is not the case. During the development of many websites, developers mistakenly believe that the use of GET/POST is only different because the data sent in the request is in the Body or the request address, and the size of the request content is different. For dangerous operations such as deletion of articles, user authorization, etc., allowing the request to be sent in GET mode, adding the ID of the article or user to the request parameter causes the data to be modified whenever the requested address is called.
Now suppose that the attacker (user ID=121), who wants to add his identity as the administrator of the site, makes A post on site A containing an image with the address http://a.com/user/grant_super_user/121
<img src="http://a.com/user/grant_super_user/121" />
Copy the code
Imagine that when the administrator sees this post, the image will automatically load and display. Thus, without the knowledge of the administrator, an operation granted to the user as administrator has been quietly executed in his capacity. At this point, attacker 121 gains administrator access to the site.
POST request utilization
Compared with GET, POST is more complex and difficult. An attacker needs to forge a form that can be submitted automatically to send a POST request.
<script>
$(function() {
$('#CSRF_forCSRFm').trigger('submit');
});
</script>
<form action="http://a.com/user/grant_super_user" id="CSRF_form" method="post">
<input name="uid" value="121" type="hidden">
</form>
Copy the code
Just find a way to automatically submit the form when the user accesses it.
Prevent principle
To prevent CSRF attacks, in fact, the essence of the website is to be able to identify which requests are initiated by abnormal users. This requests us in the request to embed additional authorization data, make the web server can distinguish between these unauthorized requests, such as a field is added in the request parameters, the value of this field from the logged in user’s cookies or page in (the field value must be for each user is random, there can be no rules to follow). The attacker can avoid this attack by forging a request without being able to retrieve a random value on the page associated with the logged-in user or the contents of the user’s current cookie.
Synchronizer token pattern
The Synchronizer Token Pattern (STP) is the technique of embedding a token in all forms on a page requested by a user and validating that token on the server side. The token can be anything, but it must be impossible for an attacker to guess or query. An attacker cannot use the correct token in a request, and therefore can identify an unauthorized request.
For sites that use Js as their primary interaction technology, CSRF’s token is written into the cookie
Set-Cookie: CSRF-token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/
Copy the code
Javascript is then used to read the value of the token and send it as the header of the HTTP request
X-CSRF-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
Copy the code
Finally, the server verifies that the token in the request header is valid.
Verification code
Using a captcha can prevent CSRF attacks, but this method requires each request to enter a captcha. Obviously, no site wants to use this crude method, and the user experience will be poor, and users will go crazy.
First, in index.php, we create a form in which we put tokens stored in the session into a hidden field so that tokens are submitted with the form when it is submitted
<? php $token = sha1(uniqid(rand(), true)); $_SESSION['token'] = $token; ? > <form action="buy.php" method="post"> <input type="hidden" name="token" value="<? =$token; ? > "/ >... Form content </form>
Copy the code
In buy.php, which verifies request parameters on the server, the tokens submitted from the form are compared with those stored in the session. If they are the same, the tokens are valid
<? php if ($_POST['token'] ! = $_SESSION['token']) {throw new \Exception(' token' is invalid); } // TOKEN valid, form content processing
Copy the code
For an attacker, the token value in the user’s page cannot be obtained when the request is forged, so the forged request can be identified.
Analyze verifyCS SRfToken middleware in Laravel framework
In Laravel framework, VerifyCSRFToken middleware is used to defend against CSRF attack.
Use {{CSRF_field()}} to generate tokens in the form of the page. This function adds a hidden field named _token to the form. The value of the hidden field is the token generated by Laravel, who uses randomly generated 40 characters as tokens to defend against CSRF attacks.
$this->put('_token', Str::random(40));
Copy the code
If the request is ajax asynchronous, you can add a token to the meta tag
<meta name="CSRF-token" content="{{ CSRF_token() }}">
Copy the code
When using jquery as a front-end framework, you can add this value to all asynchronous request headers using the following configuration
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="CSRF-token"]').attr('content')
}
});
Copy the code
When a session is enabled, Laravel generates a value named _token and stores it in the session. The token added to the page using the previous two methods uses this value. When a user request arrives, the VerifyCSRFToken middleware performs CSRF checks on eligible requests
if (
$this->isReading($request) ||
$this->runningUnitTests() ||
$this->shouldPassThrough($request) ||
$this->tokensMatch($request)
) {
return $this->addCookieToResponse($request, $next($request));
}
throw new TokenMismatchException;
Copy the code
There are four conditions in the if statement. If any of the conditions result in true, then any request is valid. Otherwise, a TokenMismatchException is thrown, telling the user that the request is invalid and there is a CSRF attack.
$this->isReading($request)
protected function isReading($request)
{
return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);
}
Copy the code
The request mode is determined. If the request mode is HEAD, GET, and OPTIONS, the request is directly allowed. You may be wondering why GET requests should also be allowed. This is because Laravel believes that all three requests are requests for query data, and if a request uses GET, no matter how many times the request is made, no matter what the request parameters are, the data should not be modified.
$this->tokensMatch($REQUEST) : $this->tokensMatch($request) : $this->tokensMatch($request)
$sessionToken = $request->session()->token(); $token = $request->input('_token') ? : $request->header('X-CSRF-TOKEN'); if (! $token && $header = $request->header('X-XSRF-TOKEN')) { $token = $this->encrypter->decrypt($header); } if (! is_string($sessionToken) || ! is_string($token)) { return false; } return hash_equals($sessionToken, $token);
Copy the code
Laravel reads the value of the _token parameter from the request, which is generated by the CSRF_field() function added in the previous form. If the request is asynchronous, the X-CSRF-Token request header is read and the TOKEN value is read from the request header.
Finally, the hash_equals function is used to verify that the token values provided in the request parameters are consistent with the token values stored in the session. If they are, the request is valid.
You may have noticed that this check also reads a request header named X-XSRF-Token. This value is used to support javascript frameworks (such as Angular) that automatically add this header to asynchronous requests. This value is read from the XSRF-token in the Cookie, so at the end of each request, Laravel sends the client a Cookie value named xSRF-Token
$response->headers->setCookie(
new Cookie(
'XSRF-TOKEN', $request->session()->token(), time() + 60 * $config['lifetime'],
$config['path'], $config['domain'], $config['secure'], false
)
);
Copy the code
This article only gives a brief introduction to CSRF, focusing on what CSRF is and how to deal with CSRF attacks. The truth is that there is no system that is absolutely secure. You have a thousand ways to defend yourself, and attackers have a thousand and one ways to attack, but we have to do our best to keep attackers out anyway. If you want to learn more about how to launch a CSRF attack, learn CSRF from scratch in this article.
As a direction of web developers, whether you are engaged in the business logic development or do a simple technical research, some safety knowledge is very necessary to pay more attention to some security dynamic direction, understand the attack and coping strategies, and to grow into a Daniel will be in your way “push for you.
This article will continue to be revised and updated, please refer to my GITHUB program ape growth plan project for the latest content, welcome Star, more exciting content please follow me.
reference
- wikipedia: Cross-site request forgery
- Cross-Site Request Forgeries
- Discussion on CSRF attack mode