2014-07-16 1 views
3

J'ai le code AJAX qui fait des requêtes POST à ​​une application Django 1.6.4. La vue dispose d'une protection CSRF activée via le django.middleware.csrf.CsrfViewMiddleware. Si je ne passe pas un cookie mais que je passe le HTTP_X_CSRFTOKEN, il échoue.En-tête Django 1.6 HTTP_X_CSRFTOKEN ignoré si le cookie csrf est manquant

Je regarde le code de django.middleware.csrf.CsrfViewMiddleware et je vois que sur la ligne 161 il vérifie pour voir si if csrf_token is None: après l'obtenir du cookie. Si c'est None, il revient. Ce n'est que par la suite qu'il vérifie le paramètre csrfmiddlewaretoken et l'en-tête de demande HTTP_X_CSRFTOKEN. Cela semble incorrect et la vérification d'une valeur csrf_token manquante ne doit être faite qu'après avoir vérifié tous les endroits possibles pour l'endroit où il pourrait être trouvé.

Quelqu'un d'autre avait des problèmes similaires? Est-ce que je vois cela incorrectement?

Répondre

0

Si vous utilisez jQuery, vous pouvez créer une fonction beforeSend qui inclut le jeton csrf. Django CSRF pour plus d'informations.

Veuillez noter que Django recherche l'en-tête X-CSRFToken et non HTTP_X_CSRFTOKEN. Au moins, c'était mon problème lors du débogage du code. (J'ai aussi vérifié le django.middleware.csrf.CsrfViewMiddleware pour cette)


Le if csrf_token is None est un contrôle supplémentaire effectué par Django. (Déclarée du commentaire dans le instruction if.

Aucun cookie CSRF. Pour les requêtes POST, nous insistons sur un cookie CSRF, et de cette façon nous pouvons éviter toutes les attaques CSRF, y compris connexion CSRF.

Je pense (pas sûr) il n'y a pas de contrôle unique à ne valider l'en-tête d'une demande de poste ajax, et Django fera des contrôles pour éviter toute forme d'attaques CSRF.

+0

Je connais le 'beforeSend' et je l'utilise. Alors que l'en-tête HTTP s'appelle X-CSRFToken, Django le rend disponible sous le nom HTTP_X_CSRFTOKEN, en préfixant le HTTP_. Voir https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META. Ceci, cependant, n'est pas mon problème. Je fournis la valeur de l'en-tête, et Django ne la regarde même pas (veuillez regarder la source Django que j'ai référencée dans le message original) –

+0

Mise à jour de ma réponse. – Eagllus

2

Je pense que la confusion pourrait soit que le cookie CSRF et le HTTP_X_CSRFTOKEN En-tête HTTP existe sur les côtés opposés de la comparaison. En d'autres termes, pour empêcher les attaques CSRF, Django compare:

CSRF valeur du cookie par rapport à la valeur de jeton POST ("de csrfmiddlewaretoken")

(ou)

valeur du cookie CSRF par rapport à la valeur d'en-tête HTTP (» HTTP_X_CSRFTOKEN ")

C'est pourquoi le cookie est toujours nécessaire. L'utilisation de l'en-tête HTTP_X_CSRFTOKEN est un substitut pour définir le jeton dans les données POST, pas un substitut du cookie.

Questions connexes