1. What is a CSRF attack?
CSRF is the abbreviation of Cross-site request forgery. For details about the CSRF attack principle and its protection, refer to the project on Github: Understanding CSRF, which is detailed and thorough.
2. How to avoid CSRF attacks in Laravel
It is easy to avoid CSRF attacks in the Laravel framework: Laravel automatically generates a CSRF Token for each user Session. This Token can be used to verify whether the login user and the initiator are the same person, if not, the request fails.
Laravel provides a global help function csrf_token to obtain the Token value. Therefore, you only need to add the following HTML code to the view submission chart to carry the Token in the request:
<Input type = "hidden" name = "_ token" value = "<? Php echo csrf_token ();?> ">
This code is equivalent to the output of the global help function csrf_field:
<? Php echo csrf_field ();?>
You can also use the following method to call the Blade template engine:
{!! Csrf_field ()!!}
Test Code
The following code is defined in routes. php:
Route: get ('testcsrf', function (){
$ Csrf_field = csrf_field ();
$ Html = <GET
<Form method = "POST" action = "/testCsrf">
{$ Csrf_field}
<Input type = "submit" value = "Test"/>
</Form>
GET;
Return $ html;
});
Route: post ('testcsrf', function (){
Return 'Success! ';
});
In the browser we enter http://laravel.app: 8000/testCsrf, click the "Test" button, the browser output:
Success!
Otherwise, if the GET route is defined as follows:
Route: get ('testcsrf', function (){
$ Html = <GET
<Form method = "POST" action = "/testCsrf">
<Input type = "submit" value = "Test"/>
</Form>
GET;
Return $ html;
});
Click "Test" to throw a TokenMismatchException.
3. Exclude the specified URL from CSRF verification
Not all requests need to avoid CSRF attacks, such as requests to obtain data through third-party APIs.
You can add the request URL to the $ response t attribute array in the VerifyCsrfToken (app/Http/Middleware/VerifyCsrfToken. php) Middleware:
<? Php
Namespace App \ Http \ Middleware;
Use Illuminate \ Foundation \ Http \ Middleware \ VerifyCsrfToken as BaseVerifier;
Class VerifyCsrfToken extends BaseVerifier
{
/**
* Specify the URLs excluded from CSRF verification
*
* @ Var array
*/
Protected $ Partition T = [
'Testcsrf'
];
}
So we refresh the page, again in the http://laravel.app: 8000/testCsrf page click the "Test" button, the page will not report an error, the normal output is as follows:
Success!
4. X-CSRF-Token and its usage
What should I do if I use Ajax to submit a POST form? We can set the Token in meta:
<Meta name = "csrf-token" content = "{csrf_token ()}">
Then, set the X-CSRF-Token request header in global Ajax and submit it:
$. AjaxSetup ({
Headers :{
'X-CSRF-TOKEN ': $ ('meta [name = "csrf-token"]'). attr ('content ')
}
});
Laravel's VerifyCsrfToken middleware checks the X-CSRF-TOKEN request header if the value is equal to the CSRF value in the Session, otherwise it does not pass.
5. X-XSRF-Token and its usage
Laravel also saves the value of CSRF to the Cookie named XSRF-TOKEN and verifies the value in VerifyCsrfToken middleware. Of course, we do not need to do anything manually, some JavaScript frameworks such as Angular will automatically help us implement them.
6. Analysis of CSRF verification principles in Laravel
After talking about so many usage methods, let's analyze the source code to see how Laravel can avoid CSRF attacks at the bottom layer:
1) when Laravel starts the Session, a token value is generated and stored in the Session (Illuminate \ Session \ Store. php 90th line start method). The source code is as follows:
Public function start ()
{
$ This-> loadSession ();
If (! $ This-> has ('_ token ')){
$ This-> regenerateToken ();
}
Return $ this-> started = true;
}
2) analyze the handle method of VerifyToken middleware. This method first uses the isReading method to determine the request method. If the request method is one of HEAD, GET, and OPTIONS, no CSRF verification is performed;
3) then, the shouldPassThrough method is used to determine whether the request route is excluded from the $ excpet attribute array. If it is excluded, verification is not performed;
4) Finally, the tokensMatch method is used to determine whether the csrf token value in the request parameter is equal to the Token value in the Session. If the value is equal, the verification is passed. Otherwise, a TokenMismatchException is thrown.
The source code is as follows:
Public function handle ($ request, Closure $ next)
{
If ($ this-> isReading ($ request) | $ this-> shouldPassThrough ($ request) | $ this-> tokensMatch ($ request )){
Return $ this-> addCookieToResponse ($ request, $ next ($ request ));
}
Throw new TokenMismatchException;
}
Note: The tokensMatch method first obtains the _ token parameter value from the Request. If the Request does not contain this parameter, it obtains the value of the X-CSRF-TOKEN Request header, if the request header does not exist, obtain the value of the X-XSRF-TOKEN request header. Note that the value of the X-XSRF-TOKEN request header needs to be decrypted by calling the decrypt method of Encrypter.