Skip to content

Commit d9935a3

Browse files
committed
feature #4141 Notes about caching pages with a CSRF Form (ricardclau)
This PR was merged into the 2.3 branch. Discussion ---------- Notes about caching pages with a CSRF Form | Q | A | ------------- | --- | Doc fix? | no | New docs? | no | Applies to | all | Fixed tickets | #1216 Commits ------- 1bc7ef2 cache_csrf_form
2 parents f43e923 + 1bc7ef2 commit d9935a3

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

Diff for: book/forms.rst

+9
Original file line numberDiff line numberDiff line change
@@ -1791,6 +1791,13 @@ section.
17911791
The ``intention`` option is optional but greatly enhances the security of
17921792
the generated token by making it different for each form.
17931793

1794+
.. caution::
1795+
1796+
CSRF tokens are meant to be different for every user. This is why you
1797+
need to be cautious if you try to cache pages with forms including this
1798+
kind of protection. For more information, see
1799+
:doc:`/cookbook/cache/form_csrf_caching`.
1800+
17941801
.. index::
17951802
single: Forms; With no class
17961803

@@ -1931,6 +1938,8 @@ Learn more from the Cookbook
19311938
* :doc:`/cookbook/form/form_customization`
19321939
* :doc:`/cookbook/form/dynamic_form_modification`
19331940
* :doc:`/cookbook/form/data_transformers`
1941+
* :doc:`/cookbook/security/csrf_in_login_form`
1942+
* :doc:`/cookbook/cache/form_csrf_caching`
19341943

19351944
.. _`Symfony Form component`: https://github.com./symfony/Form
19361945
.. _`DateTime`: http://php.net/manual/en/class.datetime.php

Diff for: cookbook/cache/form_csrf_caching.rst

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

Diff for: cookbook/cache/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ Cache
55
:maxdepth: 2
66

77
varnish
8+
form_csrf_caching

Diff for: cookbook/map.rst.inc

+1
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
* **Composer**
2526

0 commit comments

Comments
 (0)