que form csrftoken csrfmiddlewaretoken anti csrf

form - meta csrf token



¿Qué es un token CSRF? ¿Cuál es su importancia y cómo funciona? (5)

Bueno, muchachos, estoy escribiendo una aplicación Django y solo quiero una idea de qué es en realidad un token csrf y cómo protege los datos. ¿No son seguros los datos de la publicación si no usa tokens csrf?

Sé cómo usar csrf_token pero solo necesito información sobre cómo funciona.


Falsificación de solicitud entre sitios (CSRF) en palabras simples

  • Suponga que actualmente está conectado a su banca en línea en www.mybank.com
  • Supongamos que una transferencia de dinero desde mybank.com resultará en una solicitud (conceptualmente) del formulario http://www.mybank.com/transfer?to=<SomeAccountnumber>;amount=<SomeAmount> . (Su número de cuenta no es necesario porque está implícito en su nombre de usuario).
  • Visita www.cute-cat-pictures.org , sin saber que es un sitio malicioso.
  • Si el propietario de ese sitio conoce la forma de la solicitud anterior (¡fácil!) Y adivina correctamente que ha iniciado sesión en mybank.com (¡requiere algo de suerte!), Podrían incluir en su página una solicitud como http://www.mybank.com/transfer?to=123456;amount=10000 (donde 123456 es el número de su cuenta de las Islas Caimán y 10000 es un monto que anteriormente creía que estaba encantado de poseer).
  • www.cute-cat-pictures.org página www.cute-cat-pictures.org , por lo que su navegador hará esa solicitud.
  • Su banco no puede reconocer este origen de la solicitud: su navegador web enviará la solicitud junto con su cookie www.mybank.com y se verá perfectamente legítima. Ahí va tu dinero!

Este es el mundo sin tokens CSRF .

Ahora para el mejor con tokens CSRF :

  • La solicitud de transferencia se extiende con un tercer argumento: http://www.mybank.com/transfer?to=123456;amount=10000;token=31415926535897932384626433832795028841971 .
  • Ese token es un número aleatorio enorme e imposible de adivinar que mybank.com incluirá en su propia página web cuando se lo mybank.com . Es diferente cada vez que sirven cualquier página a cualquiera.
  • El atacante no puede adivinar el token, no puede convencer a su navegador web para que lo entregue (si el navegador funciona correctamente ...), por lo que el atacante no podrá crear una solicitud válida, ya que las solicitudes con el El token incorrecto (o ningún token) será rechazado por www.mybank.com .

Resultado: Mantienes tus 10000 unidades monetarias. Te sugiero que dones algo de eso a Wikipedia.

(Su experiencia puede ser diferente.)

EDITAR del comentario que vale la pena leer:

Sería digno de notar que el script de www.cute-cat-pictures.org normalmente no tiene acceso a su token anti-CSRF de www.mybank.com debido al control de acceso HTTP. Esta nota es importante para algunas personas que envían sin razón un encabezado Access-Control-Allow-Origin: * para cada respuesta de un sitio web sin saber para qué sirve, solo porque no pueden usar la API de otro sitio web.


Dejame darte un ejemplo…

Imagina que tienes un sitio web como un Twitter simplificado, alojado en a.com. Los usuarios registrados pueden ingresar texto (un tweet) en un formulario que se envía al servidor como una solicitud POST y se publica cuando se presiona el botón de envío. En el servidor, el usuario se identifica mediante una cookie que contiene su ID de sesión única, para que su servidor sepa quién publicó el Tweet.

La forma podría ser tan simple como eso:

<form action="http://a.com/tweet" method="POST"> <input type="text" name="tweet"> <input type="submit"> </form>

Ahora imagine, un tipo malo copia y pega este formulario en su sitio web malicioso, digamos b.com. La forma todavía funcionaría. Siempre que un usuario haya iniciado sesión en su Twitter (es decir, tenga una cookie de sesión válida para a.com), la solicitud POST se enviará a http://a.com/tweet y se procesará como de costumbre cuando el usuario hace clic en el botón enviar.

Hasta el momento, este no es un gran problema siempre que el usuario tenga conocimiento de lo que hace exactamente el formulario, pero ¿qué pasaría si nuestro chico malo ajusta el formulario de esta manera?

<form action="https://example.com/tweet" method="POST"> <input type="hidden" name="tweet" value="Buy great products at http://b.com/#iambad"> <input type="submit" value="Click to win!"> </form>

Ahora, si uno de sus usuarios termina en el sitio web del malo y pulsa el botón "Haga clic para ganar", el formulario se envía a su sitio web, el usuario se identifica correctamente con el ID de la sesión en la cookie y el Tweet oculto aparece. publicado.

Si nuestro tipo malo fuera aún peor, haría que el usuario inocente enviara este formulario tan pronto como abrieran su página web con JavaScript, tal vez incluso completamente escondido en un iframe invisible. Esto es básicamente la falsificación de solicitud entre sitios.

Un formulario puede ser fácilmente enviado desde cualquier lugar a cualquier lugar. En general, esa es una característica común, pero hay muchos más casos en los que es importante permitir que solo se envíe un formulario desde el dominio al que pertenece.

Las cosas son aún peores si su aplicación web no distingue entre las solicitudes POST y GET (por ejemplo, en PHP usando $ _REQUEST en lugar de $ _POST). ¡No hagas eso! Las solicitudes de modificación de datos se pueden enviar tan fácilmente como http://a.com/tweet?tweet=This+is+really+bad , incrustadas en un sitio web malicioso o incluso en un correo electrónico.

¿Cómo me aseguro de que un formulario solo pueda enviarse desde mi propio sitio web? Aquí es donde entra el token CSRF. Un token CSRF es una cadena aleatoria y difícil de adivinar. En una página con un formulario que desea proteger, el servidor generará una cadena aleatoria, el token CSRF, lo agregará al formulario como un campo oculto y también lo recordará de alguna manera, ya sea almacenándolo en la sesión o configurando una cookie que contiene el valor. Ahora la forma se vería así:

<form action="https://example.com/tweet" method="POST"> <input type="hidden" name="csrf-token" value="nc98P987bcpncYhoadjoiydc9ajDlcn"> <input type="text" name="tweet"> <input type="submit"> </form>

Cuando el usuario envía el formulario, el servidor simplemente tiene que comparar el valor del campo publicado csrf-token (el nombre no importa) con el token CSRF recordado por el servidor. Si ambas cadenas son iguales, el servidor puede continuar procesando el formulario. De lo contrario, el servidor debe dejar de procesar el formulario inmediatamente y responder con un error.

¿Por qué funciona esto? Hay varias razones por las que el chico malo de nuestro ejemplo anterior no puede obtener el token CSRF:

Copiar el código fuente estático de nuestra página a un sitio web diferente sería inútil, ya que el valor del campo oculto cambia con cada usuario. Sin el sitio web del usuario malo que conoce el token CSRF del usuario actual, su servidor siempre rechazará la solicitud POST.

Debido a que el navegador del usuario carga la página maliciosa del chico malo desde un dominio diferente (b.com en lugar de a.com), el chico malo no tiene la posibilidad de codificar un JavaScript, que carga el contenido y, por lo tanto, el token CSRF actual de nuestro usuario. su sitio web. Esto se debe a que los navegadores web no permiten las solicitudes AJAX de dominio cruzado de forma predeterminada.

El malo tampoco puede acceder a la cookie establecida por su servidor, porque los dominios no coinciden.

¿Cuándo debo protegerme contra la falsificación de solicitudes en sitios cruzados? Si puede asegurarse de no mezclar GET, POST y otros métodos de solicitud como se describe anteriormente, un buen comienzo sería proteger todas las solicitudes POST de forma predeterminada.

No tiene que proteger las solicitudes PUT y DELETE, ya que, como se explicó anteriormente, un navegador no puede enviar un formulario HTML estándar con esos métodos.

JavaScript, por otro lado, puede realizar otros tipos de solicitudes, por ejemplo, mediante el uso de la función $ .ajax () de jQuery, pero recuerde que para que las solicitudes de AJAX funcionen, los dominios deben coincidir (siempre que no configure explícitamente su servidor web) .

Esto significa que, a menudo, ni siquiera tiene que agregar un token CSRF a las solicitudes AJAX, incluso si son solicitudes POST, pero tendrá que asegurarse de que solo omita la verificación CSRF en su aplicación web si la solicitud POST es realmente una Solicitud de AJAX. Puede hacerlo buscando la presencia de un encabezado como X-Requested-With, que suelen incluir las solicitudes de AJAX. También puede establecer otro encabezado personalizado y verificar su presencia en el lado del servidor. Eso es seguro, porque un navegador no agregaría encabezados personalizados a un envío de formulario HTML regular (ver más arriba), por lo que no existe la posibilidad de que el Sr. Bad Guy simule este comportamiento con un formulario.

Si tiene dudas sobre las solicitudes AJAX, porque por alguna razón no puede buscar un encabezado como X-Requested-With, simplemente pase el token CSRF generado a su JavaScript y agregue el token a la solicitud AJAX. Hay varias maneras de hacer esto; o bien agréguelo a la carga útil como lo haría un formulario HTML normal, o agregue un encabezado personalizado a la solicitud AJAX. Siempre que su servidor sepa dónde buscarlo en una solicitud entrante y pueda compararlo con el valor original que recuerda de la sesión o la cookie, estará ordenado.


El sitio genera un token único cuando hace la página de formulario. Este token es necesario para publicar / obtener datos de nuevo en el servidor.

Dado que el token es generado por su sitio y se proporciona solo cuando se genera la página con el formulario, otro sitio no puede imitar sus formularios; no tendrán el token y, por lo tanto, no podrán publicar en su sitio.


La raíz de todo esto es asegurarse de que las solicitudes provengan de los usuarios reales del sitio. Se genera un token csrf para los formularios y debe estar vinculado a las sesiones del usuario. Se utiliza para enviar solicitudes al servidor, en el que el token las valida. Esta es una forma de protegerse contra csrf, otra sería verificar el encabezado de referencia.


Sí, los datos del post son seguros. Pero el origen de esos datos no lo es. De esta manera, alguien puede engañar al usuario con JS para que inicie sesión en su sitio mientras navega por la página web del atacante.

Para evitar eso, django enviará una clave aleatoria tanto en la cookie como en los datos del formulario. Luego, cuando los usuarios realizan POST, verificará si dos claves son idénticas. En caso de que se engañe al usuario, el sitio web de terceros no puede obtener las cookies de su sitio, lo que provoca un error de autenticación.