[pyar] [Django] Como cachear cuando hay CSRF tokens?

Esteban Castro ecastroborsani en gmail.com
Jue Jul 17 16:02:49 ART 2014


Hola!, probaste https://github.com/mozilla/django-session-csrf ??


El 17 de julio de 2014, 9:25, Andres Riancho <andres.riancho en gmail.com>
escribió:

> Gracias a todos por responder! Les cuento lo que hice al final, para
> que algun otro que este perdido con esto pueda usar mi experiencia de
> estos dias.
>
>     Lo que proponen en la lista es agregar este codigo JS:
>
> // JS code
> $.ajax({
>     url: // your csrf url,
>     type: 'GET',
>     data: {type: 'login'},  // only if you need a session id for cookie
> login
>     dataType: 'json',
>     success: function(data) {
>         $('form').each(function() {
>             $(this).append(
>                 '<input type=hidden name=csrfmiddlewaretoken ' +
>                     ' value="' + data.token + '">');
>         });
>     }
> });
>
>     No renderear el {{ csrftoken }} en en template, y tomarlo de una
> view que se ve similar a:
>
> // Django code
> # views.py, don't forget to add to urls.py
> def get_csrf(request):
>     if request.GET.get('type') == 'login':
>         request.session.set_test_cookie()
>     return JSONResponse({
>         'status': 1,
>         'token': getattr(request, 'csrf_token', 'NOTPROVIDED')
>     })
>
>     De esta manera, cualquier usuario que accede al site ve el mismo
> HTML (que en el mejor de los casos sale del cache) y el CSRF token se
> agrega una vez que el HTML se cargó. Se puede mejorar ese JS haciendo
> que se cargue el token solo cuando el form esté visible/activo/siendo
> completado por el usuario para no tener +1 request HTTP que luego no
> se use.
>
>     El problema que puede traer esto es la manera en la cual se
> verifica el token CSRF. La verificacion de CSRF en Django, por
> default, envia un input hidden con un valor random y envia el mismo
> valor en una session cookie. Esta cookie es definitivamente mala para
> los caches:
>
> "Varnish will, in the default configuration, not cache a object coming
> from the backend with a Set-Cookie header present. Also, if the client
> sends a Cookie header, Varnish will bypass the cache and go directly
> to the backend." [0]
>
>     Veamos que pasaría con la solucion propuesta de CSRF token por JS:
>
> 1- HTTP GET /
> 2- Respuesta 200 OK sin cookies con el HTML del cache
>
> 3- HTTP GET /csrf-token
> 4- Respuesta 200 OK con Set-Cookie para verificar luego CSRF
>         Set-Cookie: csrftoken=3hUXXXR9niBQVBwQsCqtsbzNZugFx1pH;
> expires=Thu, 16-Jul-2015 12:12:01 GMT; Max-Age=31449600; Path=/;
> secure
>
> 5- HTTP POST /form (usa cookie csrf)
> 6- Respuesta 200 OK del backend (no cache). Esto esta perfecto, nunca
> vamos a esperar que Varnish (u otro cache) responda a un POST. En este
> caso que tenga la cookie de csrf no cambia nada.
>
> # El usuario sigue navegando por el site despues de haber completado el
> form
>
> 7- HTTP GET /about-us (usa cookie csrf)
>     * La cookie se envia porque como vemos arriba:
>         - El path es / (todo el domain)
>         - La expiración es larga (horas)
> 8- Respuesta 200 OK proveniente del backend! <------ MALO
>     * Notar que cualquier otro usuario que hubiese navegado
> directamente a /about-us, sin previamente haber obtenido el token CSRF
> de la pagina principal donde esta el form, hubiese realizado el
> request SIN cookies, y entonces obtenido la respuesta del cache.
>
> Uf! Que problema... entonces? Entonces hay que configurar el cache de
> alguna manera especial o tomar la (potencialmente) arriesgada decision
> de deshabilitar CSRF para los forms.
>
> Luego de analizar mi situacion especifica, no siendo esto lo mejor
> para todos los casos! Deshabilite CSRF tokens para los formularios que
> estan pre-login. De esta manera el problema inicial: "Como cacheo HTML
> que tiene tokens csrf?" y tambien el caso que enumeraba antes
> desaparecen.
>
> Otro detalle que me encontré es que el tracker de Google Analytics
> setea una cookie, la cual es enviada tambien al site. Si no se sacan
> estas cookies [1], el cache va a ir hasta el backend para obtener la
> respuesta cada vez, haciendo que el cache sea simplemente un
> pasa-manos.
>
> Espero les sirva!
>
> [0] https://www.varnish-cache.org/docs/3.0/tutorial/cookies.html
> [1] https://www.varnish-cache.org/trac/wiki/VCLExampleRemovingSomeCookies
>
> 2014-07-16 21:24 GMT-03:00 Pedro Jose Pezzarini <jose2190 en gmail.com>:
> > Crea un service que solo retorne un csrftoken, y antes de enviar el
> > formulario, anexá el token como un input en hidden.
> >
> > El html te va a quedar cacheado y solo vas a enviar el token anexado.
> >
> > Espero te sirva mis 2 centavos.
> >
> > Saludos!
> >
> >
> > El 16 de julio de 2014, 21:10, ken248000 en gmail.com <ken248000 en gmail.com>
> > escribió:
> >
> >> Django carga el token en una cookie llamada "csrftoken",
> >> Deberias poder obtenerla con javascript y setear el input csrf de tu
> form.
> >>
> >>
> >> 2014-07-14 16:19 GMT-03:00 Andres Riancho <andres.riancho en gmail.com>:
> >>
> >>> Ezequiel,
> >>>
> >>>     Gracias por la pronta respuesta, tu propuesta de usar AJAX es algo
> >>> que querría evitar si es posible, principalmente porque agrega un HTTP
> >>> request para la carga del form (o al menos para la carga del token).
> >>> Con las opciones que estaba viendo, y referencie en el email original,
> >>> todo se cargaría en un solo request HTTP y sin  cambiar nada del
> >>> codigo front-end.
> >>>
> >>>     Entiendo que no existe una solución perfecta y que posiblemente
> >>> tenga que ir por este workaround pero... no hay nada mejor?
> >>>
> >>> Saludos,
> >>>
> >>> 2014-07-14 16:11 GMT-03:00 Ezequiel Gonzalez Rial <gonrial en gmail.com>:
> >>> > Hola Andrés,
> >>> >
> >>> > Si vas a cachear olvidate del CSRF. La idea de cachear es que no
> tengas
> >>> > carga dinámica. Si tal como estás diciendo lo que necesitas es que
> >>> > todas las
> >>> > vistas tengan un formulario, entonces lo que te recomiendo es que
> uses
> >>> > AJAX
> >>> > para hacer esa parte de la carga. De esa forma, lo estático se carga
> >>> > rápido
> >>> > y cacheado y después podes aplicar toda la lógica necesaria para que
> >>> > ese
> >>> > formulario aparezca como tiene que procesarse.
> >>> >
> >>> > Saludos,
> >>> >
> >>> > Ezequiel
> >>> >
> >>> >
> >>> > El 14 de julio de 2014, 15:50, Andres Riancho
> >>> > <andres.riancho en gmail.com>
> >>> > escribió:
> >>> >>
> >>> >> Lista,
> >>> >>
> >>> >>     Estuve leyendo bastante sobre como hacer caching del HTML
> generado
> >>> >> por views en Django y los problemas que existen (un gran resumen
> aqui
> >>> >> [0]); llegando a la conclusión principal de que hacer caching bien
> es
> >>> >> dificil ;) y como secundaria que existen distintas maneras de
> hacerlo:
> >>> >>
> >>> >>  * Varnish + ESI: No me gusto mucho ya que en las workstations de
> los
> >>> >> devs habría que instalar Varnish, configurarlo, etc.
> >>> >>
> >>> >>  * Two phase template rendering con cosas como django-phased [1],
> >>> >> django-twophase [2] o el partial caching de django-adv-cache-tag
> [3].
> >>> >> Ninguno de estos proyectos, salvo quizás django-adv-cache-tag tienen
> >>> >> muchos releases/contribuciones/actividad; por lo que me da la
> >>> >> impresión de que no estoy yendo por el camino correcto.
> >>> >>
> >>> >>     Entonces, que me recomiendan para hacer caching de views en
> sites
> >>> >> con Django? Cual es el mejor approach para los tokens CSRF si por
> >>> >> ejemplo tengo un contact form en el footer de todas mis views?
> >>> >>
> >>> >> [0]
> >>> >>
> https://groups.google.com/forum/#!topic/django-developers/EojHkVKxVWc
> >>> >> [1] http://django-phased.readthedocs.org/en/latest/
> >>> >> [2] https://launchpad.net/django-twophase
> >>> >> [3] http://documentup.com/twidi/django-adv-cache-tag
> >>> >>
> >>> >> Saludos,
> >>> >> --
> >>> >> Andrés Riancho
> >>> >> Project Leader at w3af - http://w3af.org/
> >>> >> Web Application Attack and Audit Framework
> >>> >> Twitter: @w3af
> >>> >> GPG: 0x93C344F3
> >>> >> _______________________________________________
> >>> >> pyar mailing list pyar en python.org.ar
> >>> >> http://listas.python.org.ar/listinfo/pyar
> >>> >>
> >>> >> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
> >>> >>
> >>> >> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre
> de
> >>> >> Argentina - http://www.usla.org.ar
> >>> >
> >>> >
> >>> >
> >>> > _______________________________________________
> >>> > pyar mailing list pyar en python.org.ar
> >>> > http://listas.python.org.ar/listinfo/pyar
> >>> >
> >>> > PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
> >>> >
> >>> > La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre
> de
> >>> > Argentina - http://www.usla.org.ar
> >>>
> >>>
> >>>
> >>> --
> >>> Andrés Riancho
> >>> Project Leader at w3af - http://w3af.org/
> >>> Web Application Attack and Audit Framework
> >>> Twitter: @w3af
> >>> GPG: 0x93C344F3
> >>> _______________________________________________
> >>> pyar mailing list pyar en python.org.ar
> >>> http://listas.python.org.ar/listinfo/pyar
> >>>
> >>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
> >>>
> >>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> >>> Argentina - http://www.usla.org.ar
> >>
> >>
> >>
> >> _______________________________________________
> >> pyar mailing list pyar en python.org.ar
> >> http://listas.python.org.ar/listinfo/pyar
> >>
> >> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
> >>
> >> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> >> Argentina - http://www.usla.org.ar
> >
> >
> >
> > _______________________________________________
> > pyar mailing list pyar en python.org.ar
> > http://listas.python.org.ar/listinfo/pyar
> >
> > PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
> >
> > La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> > Argentina - http://www.usla.org.ar
>
>
>
> --
> Andrés Riancho
> Project Leader at w3af - http://w3af.org/
> Web Application Attack and Audit Framework
> Twitter: @w3af
> GPG: 0x93C344F3
> _______________________________________________
> pyar mailing list pyar en python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> Argentina - http://www.usla.org.ar
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20140717/83664b7c/attachment.html>


More information about the pyar mailing list