Contributed by
Nicolas Grekas
in
#58095
Symfony 7.2 introduces a significant enhancement to its security features:
Stateless CSRF (Cross-Site Request Forgery) protection. This new feature
uses a combination of cookies and HTTP headers to validate non-persistent tokens.
The main advantage of this feature over the traditional CSRF techniques is
that tokens are validated without relying on server-side sessions. This makes
it suitable for applications that use HTTP caching. Additionally, not relying
on sessions ensures that users won't lose their content if they take some time
to submit a form. For example, if the session is destroyed while they are
filling in their form, the "Remember Me" feature will reconnect them, and the
form submission will still be accepted.
Enabling Stateless CSRF
To enable Stateless CSRF protection in Symfony 7.2, update your Symfony
configuration as follows:
# config/packages/framework.yaml
framework:
csrf_protection:
stateless_token_ids: ['my_stateless_token_id']
The stateless_token_ids
option is one of the parts that make the stateless
CSRF feature as safe as the traditional CSRF feature, because it explicitly lists
the token IDs allowed when using the new feature.
The following options have also been added under the csrf_protection
option:
cookie_name
: the name of the cookie to use (default:csrf-token
);check_header
: iftrue
, the CSRF token is checked in an HTTP header in
addition to a cookie (default:false
).
How Does Stateless CSRF Work?
First, the source of the request is validated using the Origin
/Referer
HTTP headers. This relies on the application being able to determine its own
target origin. If you are behind a reverse proxy, don't forget to configure your reverse proxy
to send the appropriate X-Forwarded-*
/Forwarded
HTTP headers.
Next, the request is validated using a cookie and a CsrfToken
. If the
cookie is found, it must contain the same value as the CsrfToken
. A
JavaScript snippet on the client side is responsible for performing this
double-submission. The token value should be regenerated on every request
using a cryptographically secure random generator.
If either the double-submit mechanism or Origin
/Referer
HTTP headers
are missing, it typically indicates that JavaScript is disabled on the client
side, the JavaScript snippet was not properly implemented, or the
Origin
/Referer
headers were filtered out. Requests lacking both
double-submit and origin information are considered insecure.
New Symfony applications that use Symfony Flex will have this stateless CSRF
feature enabled by default, thanks to an updated recipe that adds the following
configuration:
# config/packages/framework.yaml
framework:
form: { csrf_protection: { token_id: 'submit' } }
csrf_protection:
stateless_token_ids: ['submit', 'authenticate', 'logout']
Sponsor the Symfony project.