试图了解安全性.想知道为什么在django提交表单(POST)时,有两个单独的"元素"包含相同的csrf标记值:
- the csrftoken cookie:
COOKIES:{'csrftoken': '1effe96056e91a8f58461ad56c0d4ddc', ...
- the Form's hidden csrfmiddlewaretoken:
POST:<QueryDict: {u'csrfmiddlewaretoken':
[u'1effe96056e91a8f58461ad56c0d4ddc'], ...
Run Code Online (Sandbox Code Playgroud)
如果django在将表单发送到浏览器(GET)时将隐藏的csrf字段/值插入到表单中,并且在接收POST时期望返回相同的值,那么为什么还需要设置cookie呢?
一个更一般的问题,如果其中任何一个缺失(表单,cookie),您是否可以提供一个方案来解释如何利用它(安全攻击)?
顺便说一句,我运行了几个简单的测试,以确保django分别检查每个测试的有效性,实际上它是:
如果我在执行POST之前更改了表单的csrf值,我会收到此调试错误:
CSRF令牌丢失或不正确
如果我在执行POST之前删除了csrf cookie,我会收到不同的错误:
未设置CSRF cookie.
我只熟悉基本的csrf概念,并想了解django如何帮助抵御这些类型的攻击.
谢谢,
JD
更新:
虽然这两个答案(S.Lott和M. DeSimone)都提供了信息并且有意义,但我认为可能有更详细的解释要求在表单和cookie中都存在安全值.在stackoverflow.com外搜索时,我发现了一篇来自... Jeff Atwood的博文.
我已经包含了第三个答案(很抱歉回答我自己的问题,但我认为这是相关的补充信息),它引用了Jeff的博客文章并包含了引文.
jd.*_*jd. 19
来自Jeff Atwood的博客文章:
防止CSRF和XSRF攻击(2008年10月14日)
Felten和Zeller论文(pdf)推荐使用"双提交cookie"方法来防止XSRF:
当用户访问站点时,站点应生成(加密强)伪随机值并将其设置为用户计算机上的cookie.该网站应要求每个表单提交包括此伪随机值作为表单值以及cookie值.当POST请求发送到站点时,只有表单值和cookie值相同时才应认为该请求有效.当攻击者代表用户提交表单时,他只能修改表单的值.根据同源策略,攻击者无法读取从服务器发送的任何数据或修改cookie值.这意味着虽然攻击者可以使用表单发送他想要的任何值,但他将无法修改或读取存储在cookie中的值.由于cookie值和表单值必须相同,因此攻击者将无法成功提交表单,除非他能够猜测伪随机值.
这种方法的优点是它不需要服务器状态; 您只需设置一次cookie值,然后每次HTTP POST检查以确保其中一个提交的值包含完全相同的cookie值.两者之间的任何差异意味着可能的XSRF攻击.
该cookie用于支持AJAX.引用Django文档:
虽然上述方法可用于AJAX POST请求,但它有一些不便之处:您必须记住在每次POST请求时将CSRF令牌作为POST数据传递.因此,有一种替代方法:在每个XMLHttpRequest上,将自定义X-CSRFToken标头设置为CSRF标记的值.这通常更容易,因为许多javascript框架提供了允许在每个请求上设置标头的钩子.在jQuery中,您可以使用ajaxSend事件,如下所示:
$('html').ajaxSend(function(event, xhr, settings) {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});
Run Code Online (Sandbox Code Playgroud)
将此添加到您的站点上包含的javascript文件将确保通过jQuery创建的AJAX POST请求不会被CSRF保护捕获.
他们发现了两个不同的问题
Cookie用于验证进行连接的客户端计算机.
隐藏的表单字段用于验证表单的来源.
示例场景:客户端计算机上的用户A可以为表单添加书签.用户B登录,从今天开始获取有效的cookie.当浏览器具有来自用户B的会话的剩余cookie时,用户A可以从昨天提交无效表单字段.
通常会破坏哪些客户端/浏览器资源,
没有.
以及这些csrf字段如何帮助保护我们免受伪造请求的影响?
CSRF令牌建立身份.
一个(且仅一个)浏览器具有CSRF cookie令牌.但该浏览器可能有多个网站打开或书签形式的副本.
该浏览器上的一个(且仅一个)页面表单具有CSRF表单令牌.
浏览器和表单cookie必须匹配以确保一个浏览器/一个表单.
| 归档时间: |
|
| 查看次数: |
11205 次 |
| 最近记录: |