Init
This commit is contained in:
240
output/12.x/csrf.md
Normal file
240
output/12.x/csrf.md
Normal file
@@ -0,0 +1,240 @@
|
||||
# CSRF Protection
|
||||
|
||||
* Introduction
|
||||
* Preventing CSRF Requests
|
||||
* Excluding URIs
|
||||
* X-CSRF-Token
|
||||
* X-XSRF-Token
|
||||
|
||||
## Introduction
|
||||
|
||||
Cross-site request forgeries are a type of malicious exploit whereby
|
||||
unauthorized commands are performed on behalf of an authenticated user.
|
||||
Thankfully, Laravel makes it easy to protect your application from [cross-site
|
||||
request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
|
||||
(CSRF) attacks.
|
||||
|
||||
#### An Explanation of the Vulnerability
|
||||
|
||||
In case you're not familiar with cross-site request forgeries, let's discuss
|
||||
an example of how this vulnerability can be exploited. Imagine your
|
||||
application has a `/user/email` route that accepts a `POST` request to change
|
||||
the authenticated user's email address. Most likely, this route expects an
|
||||
`email` input field to contain the email address the user would like to begin
|
||||
using.
|
||||
|
||||
Without CSRF protection, a malicious website could create an HTML form that
|
||||
points to your application's `/user/email` route and submits the malicious
|
||||
user's own email address:
|
||||
|
||||
|
||||
|
||||
1<form action="https://your-application.com/user/email" method="POST">
|
||||
|
||||
2 <input type="email" value="[[email protected]](/cdn-cgi/l/email-protection)">
|
||||
|
||||
3</form>
|
||||
|
||||
4
|
||||
|
||||
5<script>
|
||||
|
||||
6 document.forms[0].submit();
|
||||
|
||||
7</script>
|
||||
|
||||
|
||||
<form action="https://your-application.com/user/email" method="POST">
|
||||
<input type="email" value="[[email protected]](/cdn-cgi/l/email-protection)">
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document.forms[0].submit();
|
||||
</script>
|
||||
|
||||
If the malicious website automatically submits the form when the page is
|
||||
loaded, the malicious user only needs to lure an unsuspecting user of your
|
||||
application to visit their website and their email address will be changed in
|
||||
your application.
|
||||
|
||||
To prevent this vulnerability, we need to inspect every incoming `POST`,
|
||||
`PUT`, `PATCH`, or `DELETE` request for a secret session value that the
|
||||
malicious application is unable to access.
|
||||
|
||||
## Preventing CSRF Requests
|
||||
|
||||
Laravel automatically generates a CSRF "token" for each active [user
|
||||
session](/docs/12.x/session) managed by the application. This token is used to
|
||||
verify that the authenticated user is the person actually making the requests
|
||||
to the application. Since this token is stored in the user's session and
|
||||
changes each time the session is regenerated, a malicious application is
|
||||
unable to access it.
|
||||
|
||||
The current session's CSRF token can be accessed via the request's session or
|
||||
via the `csrf_token` helper function:
|
||||
|
||||
|
||||
|
||||
1use Illuminate\Http\Request;
|
||||
|
||||
2
|
||||
|
||||
3Route::get('/token', function (Request $request) {
|
||||
|
||||
4 $token = $request->session()->token();
|
||||
|
||||
5
|
||||
|
||||
6 $token = csrf_token();
|
||||
|
||||
7
|
||||
|
||||
8 // ...
|
||||
|
||||
9});
|
||||
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
Route::get('/token', function (Request $request) {
|
||||
$token = $request->session()->token();
|
||||
|
||||
$token = csrf_token();
|
||||
|
||||
// ...
|
||||
});
|
||||
|
||||
Anytime you define a "POST", "PUT", "PATCH", or "DELETE" HTML form in your
|
||||
application, you should include a hidden CSRF `_token` field in the form so
|
||||
that the CSRF protection middleware can validate the request. For convenience,
|
||||
you may use the `@csrf` Blade directive to generate the hidden token input
|
||||
field:
|
||||
|
||||
|
||||
|
||||
1<form method="POST" action="/profile">
|
||||
|
||||
2 @csrf
|
||||
|
||||
3
|
||||
|
||||
4 <!-- Equivalent to... -->
|
||||
|
||||
5 <input type="hidden" name="_token" value="{{ csrf_token() }}" />
|
||||
|
||||
6</form>
|
||||
|
||||
|
||||
<form method="POST" action="/profile">
|
||||
@csrf
|
||||
|
||||
<!-- Equivalent to... -->
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
|
||||
</form>
|
||||
|
||||
The `Illuminate\Foundation\Http\Middleware\ValidateCsrfToken`
|
||||
[middleware](/docs/12.x/middleware), which is included in the `web` middleware
|
||||
group by default, will automatically verify that the token in the request
|
||||
input matches the token stored in the session. When these two tokens match, we
|
||||
know that the authenticated user is the one initiating the request.
|
||||
|
||||
### CSRF Tokens & SPAs
|
||||
|
||||
If you are building an SPA that is utilizing Laravel as an API backend, you
|
||||
should consult the [Laravel Sanctum documentation](/docs/12.x/sanctum) for
|
||||
information on authenticating with your API and protecting against CSRF
|
||||
vulnerabilities.
|
||||
|
||||
### Excluding URIs From CSRF Protection
|
||||
|
||||
Sometimes you may wish to exclude a set of URIs from CSRF protection. For
|
||||
example, if you are using [Stripe](https://stripe.com) to process payments and
|
||||
are utilizing their webhook system, you will need to exclude your Stripe
|
||||
webhook handler route from CSRF protection since Stripe will not know what
|
||||
CSRF token to send to your routes.
|
||||
|
||||
Typically, you should place these kinds of routes outside of the `web`
|
||||
middleware group that Laravel applies to all routes in the `routes/web.php`
|
||||
file. However, you may also exclude specific routes by providing their URIs to
|
||||
the `validateCsrfTokens` method in your application's `bootstrap/app.php`
|
||||
file:
|
||||
|
||||
|
||||
|
||||
1->withMiddleware(function (Middleware $middleware) {
|
||||
|
||||
2 $middleware->validateCsrfTokens(except: [
|
||||
|
||||
3 'stripe/*',
|
||||
|
||||
4 'http://example.com/foo/bar',
|
||||
|
||||
5 'http://example.com/foo/*',
|
||||
|
||||
6 ]);
|
||||
|
||||
7})
|
||||
|
||||
|
||||
->withMiddleware(function (Middleware $middleware) {
|
||||
$middleware->validateCsrfTokens(except: [
|
||||
'stripe/*',
|
||||
'http://example.com/foo/bar',
|
||||
'http://example.com/foo/*',
|
||||
]);
|
||||
})
|
||||
|
||||
For convenience, the CSRF middleware is automatically disabled for all routes
|
||||
when [running tests](/docs/12.x/testing).
|
||||
|
||||
## X-CSRF-TOKEN
|
||||
|
||||
In addition to checking for the CSRF token as a POST parameter, the
|
||||
`Illuminate\Foundation\Http\Middleware\ValidateCsrfToken` middleware, which is
|
||||
included in the `web` middleware group by default, will also check for the
|
||||
`X-CSRF-TOKEN` request header. You could, for example, store the token in an
|
||||
HTML `meta` tag:
|
||||
|
||||
|
||||
|
||||
1<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
Then, you can instruct a library like jQuery to automatically add the token to
|
||||
all request headers. This provides simple, convenient CSRF protection for your
|
||||
AJAX based applications using legacy JavaScript technology:
|
||||
|
||||
|
||||
|
||||
1$.ajaxSetup({
|
||||
|
||||
2 headers: {
|
||||
|
||||
3 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
|
||||
4 }
|
||||
|
||||
5});
|
||||
|
||||
|
||||
$.ajaxSetup({
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
}
|
||||
});
|
||||
|
||||
## X-XSRF-TOKEN
|
||||
|
||||
Laravel stores the current CSRF token in an encrypted `XSRF-TOKEN` cookie that
|
||||
is included with each response generated by the framework. You can use the
|
||||
cookie value to set the `X-XSRF-TOKEN` request header.
|
||||
|
||||
This cookie is primarily sent as a developer convenience since some JavaScript
|
||||
frameworks and libraries, like Angular and Axios, automatically place its
|
||||
value in the `X-XSRF-TOKEN` header on same-origin requests.
|
||||
|
||||
By default, the `resources/js/bootstrap.js` file includes the Axios HTTP
|
||||
library which will automatically send the `X-XSRF-TOKEN` header for you.
|
||||
|
||||
Reference in New Issue
Block a user