web-dev-qa-db-fra.com

Comment utiliser curl avec Django, les jetons csrf et POST demandes

J'utilise curl pour tester l'une de mes formes Django. Les appels que j'ai essayés (avec des erreurs de chaque, et sur plusieurs lignes pour la lisibilité):

(1):

curl
-d "{\"email\":\"[email protected]\"}"
--header "X-CSRFToken: [triple checked value from the source code of a page I already loaded from my Django app]"
--cookie "csrftoken=[same csrf value as above]"
http://127.0.0.1:8083/registrations/register/

(avec en-tête http et csrftoken dans le cookie) génère une erreur 400 sans qu'aucune donnée ne soit renvoyée.

(2):

curl
-d "{a:1}"
--header "X-CSRFToken:[as above]"
--cookie "csrftoken=[as above];sessionid=[from header inspection in Chrome]"
http://127.0.0.1:8083/registrations/register/

(comme dans (1) mais sans espaces dans la déclaration de propriété d'en-tête et avec sessionid dans le cookie également) entraîne la même erreur 400 sans aucune donnée retournée.

(3):

curl
-d "{a:1}"
--header "X-CSRFToken:[as above]"
http://127.0.0.1:8083/registrations/register/

(uniquement l'en-tête http avec X-CSRFToken, pas de cookie) génère le code d'erreur 403, avec le message: Le cookie CSRF n'est pas défini.

Comment puis-je tester ma forme avec curl? Quels facteurs ne sont pas pris en compte à part les valeurs de cookie et les en-têtes http?

36
Trindaz

Un mélange de la réponse de Damien et de votre exemple numéro 2 a fonctionné pour moi. J'ai utilisé une simple page de connexion pour tester, je m'attends à ce que votre vue d'enregistrement soit similaire. La réponse de Damien fonctionne presque, mais il manque le cookie sessionid.

Je recommande une approche plus robuste. Plutôt que de saisir manuellement les cookies d'autres demandes, essayez d'utiliser le système de gestion des cookies intégré de Curl pour simuler une interaction complète de l'utilisateur. De cette façon, vous réduisez le risque d'erreur:

$ curl -v -c cookies.txt -b cookies.txt Host.com/registrations/register/
$ curl -v -c cookies.txt -b cookies.txt -d "[email protected]&a=1&csrfmiddlewaretoken=<token from cookies.txt>" Host.com/registrations/register/

La première boucle simule l'utilisateur qui arrive en premier à la page avec une requête GET, et tous les cookies nécessaires sont sauvegardés. La deuxième boucle simule le remplissage des champs de formulaire et leur envoi en tant que POST. Notez que vous devez inclure le champ csrfmiddlewaretoken dans les données POST, comme suggéré par Damien.

26
Kevin S.

Essayer:

curl
 -d "[email protected]&a=1"
 http://127.0.0.1:8083/registrations/register/

Notez en particulier le format de l'argument -d.

Toutefois, cela ne fonctionnera probablement pas, car votre vue nécessite probablement une demande POST au lieu d'une demande GET. Puisqu'il s'agira de modifier des données, pas seulement de retourner des informations.

La protection CSRF n'est requise que pour les requêtes "non sécurisées" (POST, PUT, DELETE). Cela fonctionne en vérifiant le cookie 'csrftoken' avec le champ de formulaire 'csrfmiddlewaretoken' ou l'en-tête http 'X-CSRFToken'.

Alors:

curl
 -X POST
 -d "[email protected]&a=1&csrfmiddlewaretoken={inserttoken}"
 --cookie "csrftoken=[as above]"
 http://127.0.0.1:8083/registrations/register/

Il est également possible d'utiliser --header "X-CSRFToken: {token}" au lieu de l'inclure dans les données du formulaire.

11
Damien Ayers

J'ai travaillé avec curl comme ça

  • Vous devez soumettre csrftoken dans l'en-tête en tant que X-CSRFToken.
  • Vous devez soumettre les données de formulaire au format JSON . Demo,

D'abord, nous allons chercher csrf_token & store dans cookie.txt (ou cookie.jar comme ils l'appellent)

$ curl -c cookie.txt http://localhost.com:8000/ 

contenu cookie.txt

# Netscape HTTP Cookie File
# http://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
localhost.com  FALSE   /   FALSE   1463117016  csrftoken   vGpifQR12BxT07moOohREGmuKp8HjxaE

Ensuite, nous renvoyons le nom d'utilisateur et le mot de passe au format json. (vous pouvez l'envoyer de manière normale). Vérifiez l'échappement de données JSON.

$curl --cookie cookie.txt http://localhost.com:8000/login/   -H "Content-Type: application/json" -H "X-CSRFToken: vGpifQR12BxT07moOohREGmuKp8HjxaE" -X POST -d "{\"username\":\"username\",\"password\":\"password\"}" 
{"status": "success", "response_msg": "/"}
$

vous pouvez stocker les retours du nouveau cookie de session csrf_token dans le même fichier ou dans un nouveau fichier (j'ai stocké dans le même fichier à l'aide de l'option -c.)

$curl --cookie cookie.txt http://localhost.com:8000/login/   -H "Content-Type: application/json" -H "X-CSRFToken: kVgzzB6MJk1RtlVnyzegEiUs5Fo3VRqF" -X POST -d "{\"username\":\"username\",\"password\":\"password\"}" -c cookie.txt

-Contenu de cookie.txt

# Netscape HTTP Cookie File
# http://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

localhost.com  FALSE   /   FALSE   1463117016  csrftoken   vGpifQR12BxT07moOohREGmuKp8HjxaE
#HttpOnly_localhost.com    FALSE   /   FALSE   1432877016  sessionid   cg4ooly1f4kkd0ifb6sm9p

Lorsque vous stockez le nouveau cookie csrf_token & id de session dans cookie.txt, vous pouvez utiliser le même cookie.txt sur l'ensemble du site Web.

Vous lisez les cookies de la demande précédente de cookie.txt (--cookie) et écrivez de nouveaux cookies à partir de la réponse dans le même cookie.txt (-c).

Le formulaire de lecture et de soumission fonctionne désormais avec csrf_token et l'identifiant de session.

$curl --cookie cookie.txt http://localhost.com:8000/home/
4
Netro

Voici comment je l'ai fait, en utilisant le tutoriel sur la structure restante

ouvrez un navigateur, par exemple chrome puis en appuyant sur F12, ouvrez l'onglet développeur et surveillez le réseau, connectez-vous à l'aide de vos informations d'identification utilisateur et obtenez votre jeton CRSF en surveillant le POST

puis en boucle exécuter:

curl http://127.0.0.1:8000/snippets/ \
 -X POST \
 -H "Content-Type: application/json" \
 -H "Accept: text/html,application/json" \
 -H "X-CSRFToken: the_token_value" \
 -H "Cookie: csrftoken=the_token_value" \
 -u your_user_name:your_password \
 -d '{"title": "first cookie post","code": "print hello world"}' 

Je pense que c'est plus propre de ne pas mettre le jeton dans le corps, mais plutôt l'en-tête utilisant X-CSRFToken

3
Dr Manhattan

curl-auth-csrf est un outil open source basé sur Python, capable de le faire pour vous: "Outil Python qui imite cURL, mais effectue une connexion et gère tous les jetons CSRF. pour gratter le code HTML normalement accessible uniquement lorsque vous êtes connecté. "

Ce serait votre syntaxe:

echo -n YourPasswordHere | ./curl-auth-csrf.py -i http://127.0.0.1:8083/registrations/register/ -d '[email protected]&a=1' http://127.0.0.1:8083/registrations/register/

Cela transmettra les données POST comme indiqué, mais aussi pour inclure le mot de passe transmis via stdin. Je suppose que la page que vous visitez après "login" est la même page.

Divulgation complète: je suis l'auteur de curl-auth-csrf.

1
j0nam1el

X-CSRFToken dans les en-têtes doit simplement être identique à csrftoken dans le cookie.

Exemple:

curl -v http://www.markjour.com/login/ -H "X-CSRFToken: 123" -b "csrftoken=123" -d "username=admin&password=admin"
0
markjour