Skip to content

Commit 8164304

Browse files
committed
cache_csrf_form
1 parent 4ea4dfe commit 8164304

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

book/forms.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,13 @@ section.
17651765
The ``intention`` option is optional but greatly enhances the security of
17661766
the generated token by making it different for each form.
17671767

1768+
.. caution::
1769+
1770+
CSRF tokens are meant to be different for every user. This is why you
1771+
need to be cautious if you try to cache pages with forms including this
1772+
kind of protection. For more information, see
1773+
:doc:`/cookbook/cache/form_csrf_caching`.
1774+
17681775
.. index::
17691776
single: Forms; With no class
17701777

@@ -1905,6 +1912,8 @@ Learn more from the Cookbook
19051912
* :doc:`/cookbook/form/form_customization`
19061913
* :doc:`/cookbook/form/dynamic_form_modification`
19071914
* :doc:`/cookbook/form/data_transformers`
1915+
* :doc:`/cookbook/security/csrf_in_login_form`
1916+
* :doc:`/cookbook/cache/form_csrf_caching`
19081917

19091918
.. _`Symfony2 Form component`: https://github.com/symfony/Form
19101919
.. _`DateTime`: http://php.net/manual/en/class.datetime.php

cookbook/cache/form_csrf_caching.rst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
.. index::
2+
single: Cache; CSRF; Forms
3+
4+
Caching Pages that Contain CSRF Protected Forms
5+
===============================================
6+
7+
CSRF - or `Cross-site request forgery`_ - is a method by which a malicious
8+
user attempts to make your legitimate users unknowingly submit data that
9+
they don't intend to submit. Fortunately, CSRF attacks can be prevented by
10+
using a CSRF token inside your forms.
11+
12+
For more information about how this protection works in Symfony, please
13+
check :ref:`CSRF Protection <forms-csrf>`.
14+
15+
Why Varnish does not Cache these Pages by Default
16+
-------------------------------------------------
17+
18+
There are many ways to generate unique tokens for each user but in order get
19+
them validated when the form is submitted, you need to store them inside the
20+
PHP Session.
21+
22+
If you are using Varnish or some similar reverse proxy cache and you try to cache
23+
pages containing forms with CSRF token protection, you will see that, by default,
24+
Varnish fails to cache them.
25+
26+
This happens because a cookie is sent in order to preserve the PHP session open and
27+
Varnish default behaviour is to not cache HTTP requests with cookies.
28+
29+
If you think about it, if you managed to cache the form you would end up
30+
with many users getting the same token in the form generation. When these
31+
users try to send the form to the server, the CSRF validation will fail for
32+
them because the expected token is stored in their session and different
33+
for each user.
34+
35+
How to Cache most of the Page and still Be Able to Use CSRF Protection
36+
----------------------------------------------------------------------
37+
38+
To cache a page that contains a CSRF token you can use more advanced caching
39+
techniques like `ESI`_ fragments, having a TTL for the full page and embedding
40+
the form inside an ESI tag with no cache at all.
41+
42+
Another option to be able to cache that heavy page would be loading the form
43+
via an uncached AJAX request but cache the rest of the HTML response.
44+
45+
Or you can even load just the CSRF token with an AJAX request and replace the
46+
form field value with it.
47+
48+
.. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery
49+
.. _`ESI`: http://www.w3.org/TR/esi-lang
50+
.. _`Security CSRF Component`: https://github.com/symfony/security-csrf

cookbook/cache/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ Cache
55
:maxdepth: 2
66

77
varnish
8+
form_csrf_caching

cookbook/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* :doc:`/cookbook/cache/index`
2121

2222
* :doc:`/cookbook/cache/varnish`
23+
* :doc:`/cookbook/cache/form_csrf_caching`
2324

2425
* :doc:`/cookbook/configuration/index`
2526

0 commit comments

Comments
 (0)