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

时间:2012-05-16 23:53:54

标签: django curl django-forms csrf django-csrf

我正在使用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/

(在Cookie中使用http标头和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/

(如在(1)中但在header属性声明中没有空格,并且在cookie中也没有sessionid)导致相同的400错误而没有返回数据。

(3):

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

(只有带有X-CSRFToken的http标头,没有cookie)会导致错误代码403,并显示消息:未设置CSRF cookie。

如何用curl测试我的表单?除了cookie值和http标头之外,我还没有考虑哪些因素?

6 个答案:

答案 0 :(得分:27)

达米恩的回应和你的榜样2的混合物为我工作。我使用一个简单的登录页面进行测试,我希望您的注册视图类似。达米恩的回答几乎可以奏效,但错过了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发送。请注意,您必须按照Damien的建议在POST数据中包含csrfmiddlewaretoken字段。

答案 1 :(得分:13)

尝试:

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}"而不是将其包含在表单数据中。

答案 2 :(得分:6)

我像这样使用curl

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

首先我们将获取csrf_token&amp;存储在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.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

当你存储新的csrf_token&amp;在cookie.txt中的会话ID cookie,您可以在网站上使用相同的cookie.txt。

您正在从cookie.txt(--cookie)的先前请求中读取Cookie,并在同一cookie.txt(-c)中写入响应中的新Cookie。

阅读&amp;提交表单现在适用于csrf_token&amp;会话ID。

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

答案 3 :(得分:3)

以下是我使用其余框架教程

的方法

打开浏览器,例如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

将令牌放在正文中而是放入标题

答案 4 :(得分:1)

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传递的密码。我假设您在“登录”后访问的页面是同一页面。

完全披露:我是curl-auth-csrf的作者。

答案 5 :(得分:0)

标题中的

X-CSRFToken只需与Cookie中的csrftoken相同。

示例:

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