39đ
A mixture of Damienâs response and your example number 2 worked for me. I used a simple login page to test, I expect that your registration view is similar. Damienâs response almost works, but is missing the sessionid
cookie.
I recommend a more robust approach. Rather than manually entering the cookies from other requests, try using curlâs built in cookie management system to simulate a complete user interaction. That way, you reduce the chance of making an error:
$ curl -v -c cookies.txt -b cookies.txt host.com/registrations/register/
$ curl -v -c cookies.txt -b cookies.txt -d "email=user@site.com&a=1&csrfmiddlewaretoken=<token from cookies.txt>" host.com/registrations/register/
The first curl simulates the user first arriving at the page with a GET request, and all the necessary cookies are saved. The second curl simulates filling in the form fields and sending them as a POST. Note that you have to include the csrfmiddlewaretoken
field in the POST data, as suggested by Damien.
16đ
Try:
curl
-d "email=test@test.com&a=1"
http://127.0.0.1:8083/registrations/register/
Notice especially the format of the -d
argument.
However, this probably wonât work, as your view likely needs a POST request instead of a GET request. Since it will be modifying data, not just returning information.
CSRF protection is only required for âunsafeâ requests (POST, PUT, DELETE). It works by checking the âcsrftokenâ cookie against either the âcsrfmiddlewaretokenâ form field or the âX-CSRFTokenâ http header.
So:
curl
-X POST
-d "email=test@test.com&a=1&csrfmiddlewaretoken={inserttoken}"
--cookie "csrftoken=[as above]"
http://127.0.0.1:8083/registrations/register/
Itâs also possible to use --header "X-CSRFToken: {token}"
instead of including it in the form data.
- [Django]-Why doesn't django's model.save() call full_clean()?
- [Django]-How do you serialize a model instance in Django?
- [Django]-Django download a file
10đ
I worked with curl like this
- You have to submit csrftoken in header as X-CSRFToken.
- You have to submit form data in JSON format.
Demo,
First we will fetch csrf_token & store in cookie.txt (or cookie.jar as they call it)
$ curl -c cookie.txt http://localhost.com:8000/
cookie.txt content
# 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
Next we resend the username, password in json format. (you may send it in normal way). Check the json data escape.
$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": "/"}
$
you can store the returns new csrf_token session cookie in same file or new file (I have stored in same file using 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
-Content of 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
When you store new csrf_token & session id cookie in cookie.txt, you can use same cookie.txt across the website.
You am reading cookies from previous request from cookie.txt (âcookie) and writing new cookies from response in same cookie.txt (-c).
Reading & submitting form now works with csrf_token & session id.
$curl --cookie cookie.txt http://localhost.com:8000/home/
- [Django]-'WSGIRequest' object has no attribute 'user' Django admin
- [Django]-Stack trace from manage.py runserver not appearing
- [Django]-ImproperlyConfiguredError about app_name when using namespace in include()
6đ
Here is how i did it, using the rest framework tutorial
open a browser e.g. chrome then pressing F12 open the developer tab and monitor the Network, login using your user credentials and get your CRSF token from monitoring the POST
then in curl execute:
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"}'
I think its cleaner to not put the token in the body but rather the header using X-CSRFToken
- [Django]-How can one use enums as a choice field in a Django model?
- [Django]-Django urls without a trailing slash do not redirect
- [Django]-Modulus % in Django template
1đ
curl-auth-csrf is a Python-based open-source tool capable of doing this for you: âPython tool that mimics cURL, but performs a login and handles any Cross-Site Request Forgery (CSRF) tokens. Useful for scraping HTML normally only accessible when logged in.â
This would be your syntax:
echo -n YourPasswordHere | ./curl-auth-csrf.py -i http://127.0.0.1:8083/registrations/register/ -d 'email=test@test.com&a=1' http://127.0.0.1:8083/registrations/register/
This will pass along the POST data as listed, but also to include the password passed via stdin. I assume that the page you visit after âloginâ is the same page.
Full disclosure: Iâm the author of curl-auth-csrf.
- [Django]-Django: manage.py does not print stack trace for errors
- [Django]-How do you limit list objects template side, rather than view side
- [Django]-Django queries: how to filter objects to exclude id which is in a list?
0đ
To make the CurlâDjango communication work, I had to provide
- the CSRF token in the
X-CSRFToken
header field; - the CSRF token in the
Cookie
header field; - the session identifier in the
Cookie
header field.
$ curl -v -X PUT -H "X-CSRFToken: {csrf_token}" --cookie "csrftoken={csrf_token};sessionid={session_id}" http://localhost:{port}{path}?{query}
* Trying 127.0.0.1:{port}...
* Connected to localhost (127.0.0.1) port {port} (#0)
> PUT {path}?{query} HTTP/1.1
> Host: localhost:{port}
> User-Agent: curl/7.79.1
> Accept: */*
> Cookie: csrftoken={csrf_token};sessionid={session_id}
> X-CSRFToken: {csrf_token}
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 204 No Content
< Vary: Accept, Accept-Language, Cookie
< Allow: DELETE, PUT, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Language: fr-fr
< Content-Length: 0
< Server-Timing: TimerPanel_utime;dur=159.20299999999975;desc="User CPU time", TimerPanel_stime;dur=70.73100000000032;desc="System CPU time", TimerPanel_total;dur=229.93400000000008;desc="Total CPU time", TimerPanel_total_time;dur=212.03255653381348;desc="Elapsed time", SQLPanel_sql_time;dur=7.846832275390625;desc="SQL 7 queries", CachePanel_total_time;dur=0;desc="Cache 0 Calls"
< X-Content-Type-Options: nosniff
< Referrer-Policy: origin,origin-when-cross-origin
< Cross-Origin-Opener-Policy: same-origin
< Server: Werkzeug/2.0.0 Python/3.9.13
< Date: Wed, 14 Sep 2022 16:27:04 GMT
<
* Closing connection 0
Failed attempts
If I omit the CSRF token in the X-CSRFToken
header field, I get a 403 (Forbidden)
status code:
$ curl -v -X PUT --cookie "csrftoken={csrf_token};sessionid={session_id}" http://localhost:{port}{path}?{query}
* Trying 127.0.0.1:{port}...
* Connected to localhost (127.0.0.1) port {port} (#0)
> PUT {path}?{query} HTTP/1.1
> Host: localhost:{port}
> User-Agent: curl/7.79.1
> Accept: */*
> Cookie: csrftoken={csrf_token};sessionid={session_id}
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 403 Forbidden
< Content-Type: application/json
< Vary: Accept, Accept-Language, Cookie
< Allow: DELETE, PUT, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Language: fr-fr
< Content-Length: 116
< Server-Timing: TimerPanel_utime;dur=79.28900000000283;desc="User CPU time", TimerPanel_stime;dur=10.49199999999928;desc="System CPU time", TimerPanel_total;dur=89.78100000000211;desc="Total CPU time", TimerPanel_total_time;dur=111.31906509399414;desc="Elapsed time", SQLPanel_sql_time;dur=4.807949066162109;desc="SQL 3 queries", CachePanel_total_time;dur=0;desc="Cache 0 Calls"
< X-Content-Type-Options: nosniff
< Referrer-Policy: origin,origin-when-cross-origin
< Cross-Origin-Opener-Policy: same-origin
< Server: Werkzeug/2.0.0 Python/3.9.13
< Date: Wed, 14 Sep 2022 16:49:13 GMT
<
* Closing connection 0
{"detail":[{"location":"non_field_errors","message":"CSRF Failed: CSRF token missing.","type":"permission_denied"}]}
If I omit the CSRF token in the Cookie
header field, I get a 403 (Forbidden)
status code:
$ curl -v -X PUT -H "X-CSRFToken: {csrf_token}" --cookie "sessionid={session_id}" http://localhost:{port}{path}?{query}
* Trying 127.0.0.1:{port}...
* Connected to localhost (127.0.0.1) port {port} (#0)
> PUT {path}?{query} HTTP/1.1
> Host: localhost:{port}
> User-Agent: curl/7.79.1
> Accept: */*
> Cookie: sessionid={session_id}
> X-CSRFToken: {csrf_token}
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 403 Forbidden
< Content-Type: application/json
< Vary: Accept, Accept-Language, Cookie
< Allow: DELETE, PUT, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Language: fr-fr
< Content-Length: 117
< Server-Timing: TimerPanel_utime;dur=81.76699999999926;desc="User CPU time", TimerPanel_stime;dur=10.824999999996976;desc="System CPU time", TimerPanel_total;dur=92.59199999999623;desc="Total CPU time", TimerPanel_total_time;dur=112.99705505371094;desc="Elapsed time", SQLPanel_sql_time;dur=5.406379699707031;desc="SQL 3 queries", CachePanel_total_time;dur=0;desc="Cache 0 Calls"
< X-Content-Type-Options: nosniff
< Referrer-Policy: origin,origin-when-cross-origin
< Cross-Origin-Opener-Policy: same-origin
< Server: Werkzeug/2.0.0 Python/3.9.13
< Date: Wed, 14 Sep 2022 16:53:39 GMT
<
* Closing connection 0
{"detail":[{"location":"non_field_errors","message":"CSRF Failed: CSRF cookie not set.","type":"permission_denied"}]}
If I omit the session identifier in the Cookie
header field, I get a 401 (Unauthorized)
status code:
$ curl -v -X PUT -H "X-CSRFToken: {csrf_token}" --cookie "csrftoken={csrf_token}" http://localhost:{port}{path}?{query}
* Trying 127.0.0.1:{port}...
* Connected to localhost (127.0.0.1) port {port} (#0)
> PUT {path}?{query} HTTP/1.1
> Host: localhost:{port}
> User-Agent: curl/7.79.1
> Accept: */*
> Cookie: csrftoken={csrf_token}
> X-CSRFToken: {csrf_token}
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 401 Unauthorized
< Content-Type: application/json
< Vary: Accept, Accept-Language, Cookie
< Allow: DELETE, PUT, OPTIONS
< X-Frame-Options: SAMEORIGIN
< Content-Language: fr-fr
< Content-Length: 129
< Server-Timing: TimerPanel_utime;dur=21.655999999993014;desc="User CPU time", TimerPanel_stime;dur=4.543999999995663;desc="System CPU time", TimerPanel_total;dur=26.199999999988677;desc="Total CPU time", TimerPanel_total_time;dur=41.02301597595215;desc="Elapsed time", SQLPanel_sql_time;dur=0;desc="SQL 0 queries", CachePanel_total_time;dur=0;desc="Cache 0 Calls"
< X-Content-Type-Options: nosniff
< Referrer-Policy: origin,origin-when-cross-origin
< Cross-Origin-Opener-Policy: same-origin
< Server: Werkzeug/2.0.0 Python/3.9.13
< Date: Wed, 14 Sep 2022 16:58:33 GMT
<
* Closing connection 0
{"detail":[{"location":"non_field_errors","message":"Informations d'authentification non fournies.","type":"not_authenticated"}]}
- [Django]-Accepting email address as username in Django
- [Django]-How can I use redis with Django?
- [Django]-In Django Admin how do I disable the Delete link