如何在Django,csrf令牌和POST请求中使用curl

6vl6ewon  于 2022-11-13  发布在  Go
关注(0)|答案(6)|浏览(180)

我正在使用curl测试我的一个Django表单。我已经尝试过的调用(每个都有错误,并且为了可读性需要多行):
(1):

curl
-d "{\"email\":\"test@test.com\"}"
--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/

(with HTTP头和cookie中的csrftoken)将导致400错误,且不返回任何数据。
(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/

(as在(1)中,但在信头属性宣告中没有空格,而且在cookie中也有sessionid)会导致相同的400错误,而且不会传回任何数据。
(3):

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

(only具有X-CSRFToken的HTTP报头,没有cookie)导致错误代码403,消息为:未设置CSRF cookie。
我如何用curl测试我的表单?除了cookie值和http头,我没有考虑哪些因素?

qqrboqgw

qqrboqgw1#

Damien的回答和你的例子2的混合对我很有效。我用一个简单的登录页面来测试,我希望你的注册视图是类似的。Damien的回答几乎有效,但是缺少sessionid cookie。
我推荐一种更健壮的方法。与其手动输入来自其他请求的cookie,不如尝试使用curl内置的cookie管理系统来模拟完整的用户交互。这样,您就可以减少出错的几率:

$ 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/

第一个curl模拟用户第一次通过GET请求到达页面,并保存所有必要的cookie。第二个curl模拟填写表单字段并将其作为POST发送。注意,您必须在POST数据中包括csrfmiddlewaretoken字段,如Damien所建议的。

ruoxqz4g

ruoxqz4g2#

请尝试:

curl
 -d "email=test@test.com&a=1"
 http://127.0.0.1:8083/registrations/register/

请特别注意-d参数的格式。
然而,这可能不起作用,因为您的视图可能需要POST请求而不是GET请求,因为它将修改数据,而不仅仅是返回信息。
只有“不安全”的请求(POST、PUT、DELETE)才需要CSRF保护。它的工作原理是根据"csrfmiddlewaretoken“表单字段或”X-CSRFToken“http标头检查”csrftoken“Cookie。
因此:

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

也可以使用--header "X-CSRFToken: {token}",而不是将其包含在表单数据中。

cig3rfwq

cig3rfwq3#

我 和 curl 一起 工作 的 时候

  • 必须 在 标 头 中 将 csrftoken 作为 X-CSRFToken 提交 。
  • 您 必须 以 JSON 格式 提交 表单 数据 演示 ,

首先 , 我们 将 获取 csrf _ token 并 存储 在 cookie.txt ( 或 他们 所 称 的 cookie.jar ) 中

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

中 的 每 一 个
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

格式
接下来 我们 重新 发送 json 格式 的 用户 名 和 密码 。 ( 你 可以 用 正常 的 方式 发送 ) 。 检查 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": "/"}
$

格式
您 可以 将 返回 的 新 csrf _ token 会话 cookie 存储 在 同一 个 文件 或 新 文件 中 ( 我 已经 使用 选项 - 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

格式

  • Cookie 的 内容
# 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

格式
当 您 在 cookie.txt 中 存储 新 的 csrf _ token 和 会话 ID cookie 时 , 您 可以 在 整个 网站 上 使用 相同 的 cookie.txt 。
您 正在 从 cookie.txt ( - - cookie ) 中 读取 来自 上 一 个 请求 的 cookie , 并 在 同一 cookie.txt ( - c ) 中 写入 来自 响应 的 新 cookie 。
读取 和 提交 表单 现在 可以 使用 csrf _ token 和 会话 ID 。

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

格式

jfgube3f

jfgube3f4#

下面是我如何使用rest框架教程完成的。
打开浏览器(例如chrome),然后按F12,打开开发人员选项卡并监控网络,使用您的用户凭据登录,并通过监控POST获取您的CRSF令牌
然后在curl中执行:

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"}'

我认为使用X-CSRFToken不将令牌放在主体中而是放在标头中会更干净一些

aydmsdu9

aydmsdu95#

curl-auth-csrf是一个基于Python的开源工具,能够为您完成以下任务:Python工具,模仿cURL,但执行登录并处理任何跨站请求伪造(CSRF)令牌。用于抓取通常只有在登录时才能访问的HTML。
您的语法如下:

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/

这将沿着的POST数据,但也包括通过stdin传递的密码。我假设您在“登录”后访问的页面是同一个页面。
充分披露:我是“卷发验证”的作者。

m0rkklqb

m0rkklqb6#

为了让Curl-Django的沟通工作正常,我必须提供

  • X-CSRFToken报头字段中的CSRF令牌;
  • Cookie报头字段中的CSRF令牌;
  • X1 M2 N1 X报头字段中的会话标识符。
$ 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

次失败的尝试

如果我省略了X-CSRFToken头字段中的CSRF标记,我会得到一个403 (Forbidden)状态代码:

$ 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"}]}

如果我省略了Cookie头字段中的CSRF标记,我会得到一个403 (Forbidden)状态代码:

$ 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"}]}

如果省略了Cookie头字段中的会话标识符,则会得到一个401 (Unauthorized)状态代码:

$ 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"}]}

相关问题