Django documentation on its CSRF protection表示:
此外,对于HTTPS请求, 严格的引用检查是通过 CsrfViewMiddleware。这是必要的 解决一个中间人攻击 这可以在HTTPS下进行 使用会话独立的nonce,到期 HTTP'Set-Cookie'的事实 (不幸的是)接受了标题 由与网站交谈的客户 在HTTPS下。 (引用者检查不是 为HTTP请求完成,因为 Referer头的存在不是 在HTTP下足够可靠。)
我无法直观地了解此攻击的工作原理。有人可以解释一下吗?
更新:
Django文档中的措辞似乎意味着存在一种特定类型的中间人攻击(这导致我假设成功的CSRF),它与会话无关的nonce一起工作(但不适用于特定于事务的nonce等) 。,我想)并涉及使用'Set-Cookie'标题
所以我想知道这种特定类型的攻击是如何起作用的。
答案 0 :(得分:4)
攻击者可以使用Set-Cookie设置CSRF cookie,然后在POST表单数据中提供匹配的令牌。由于该站点没有将会话cookie绑定到CSRF cookie,因此无法确定CSRF令牌+ cookie是否为正版(其中一个的散列等不起作用,因为攻击者可以获得有效的一对直接来自网站,并在攻击中使用该对。)
Directly from the django project
(我用Google搜索session independent nonce。)
答案 1 :(得分:2)
这是一次此类MitM攻击的very detailed description。以下是简略的简化改编:
修改HTTP提供的页面(例如, http://foo.com/browse )以获得提交到HTTPS POST端点的自动提交表单(例如, {{3 }} 强>)。同时将其CSRF cookie设置为与您的令牌匹配:
<script type="text/javascript">
function loadFrame(){
var form=document.getElementById('attackform');
// Make sure that the form opens in a hidden frame so user doesn't notice
form.setAttribute('target', 'hiddenframe');
form.submit();
}
</script>
<form name="attackform" id="attackform" style="display:none" method="POST"
action="http://foo.com/check_out">
<input type="text" name="expensive-thing" value="buy-it-now"/>
<input type="text" name="csrf" value="csrf-token-value"/>
</form>
<iframe name="hiddenframe" style="display:none" id="hiddenframe"></iframe>
<XXX onload="loadFrame();">
答案 2 :(得分:0)
Man-In-The-Middle攻击用非常简单的术语解释。想象一下,两个人正在互相交谈,在他们开始互相交谈之前,他们会在他们开始双向沟通之前进行握手。当第三个人开始分析两个人如何沟通这两个人时(他们的习惯是什么?他们在彼此说话之前是否进行了特殊的握手?他们什么时候喜欢互相交谈等等) ,第三个人可以塑造他/她的沟通,使他/她可以将自己嵌入到对话中,并充当原始两个人认为他们彼此说话的调解员。
现在采取这个概念并降低到极客水平。当PC,路由器,程序等与另一个节点通信到网络时,通过认证,确认或两者进行双向通信。如果第三方可以确定所需的事件序列(会话ID,会话cookie,流量中的下一个确认/传输/终止序列等),则恶意第三方可以将自己的流量镜像为合法节点,将流量泛洪到其中一个合法节点,如果它们得到正确的事件序列,恶意的第三个节点就会被接受为合法节点。
答案 3 :(得分:0)
假设我们有一个基于Django的网站和一个恶意的中间人。在一般情况下,该网站甚至不必为http://
页提供服务以使攻击成功。在Django的情况下,它可能需要在普通http://
上至少提供一个受CSRF保护的页面(参见下面的解释)。
攻击者首先需要获得语法上有效的CSRF令牌。对于某些类型的令牌(如简单的随机字符串),她可能只能制作一个令牌。对于Django的混乱令牌,她可能必须从包含CSRF的http://
页面获取一个(例如在隐藏的表单字段中)。
关键是Django的CSRF令牌与用户的会话或任何其他已保存的状态无关。 Django只会查看cookie和表单值(或AJAX的标题)之间是否匹配。所以任何有效的令牌都可以。
用户通过http://
请求页面。攻击者可以自由修改响应,因为它是未加密的。她使用她的恶意CSRF令牌执行Set-Cookie
,并更改页面以包含隐藏的表单 - 并将Javascript提交给POSTs
到https://
端点。当然,这种形式包括具有CSRF值的字段。
当用户的浏览器加载响应时,它会存储Set-Cookie
标头指定的CSRF cookie,然后运行Javascript以提交表单。它将POST
与恶意CSRF cookie一起发送到https://
端点。
(relevant RFC中讨论了将http://
设置的Cookie发送到https://
端点的“不幸”事实:“活跃的网络攻击者还可以将Cookie注入Cookie通过模拟来自https://example.com/
的响应并注入http://example.com/
标头发送到Set-Cookie
的标头。example.com
处的HTTPS服务器将无法将这些Cookie与其自行设置的Cookie区分开来在HTTPS响应中。即使example.com
仅使用HTTPS,活动网络攻击者也可能利用此功能对example.com
发起攻击。“)
最后,Django服务器收到恶意POST
请求。它将CSRF cookie(由攻击者设置)与表单中的值(由攻击者设置)进行比较,并看出它们是相同的。它允许恶意请求。
因此,为了避免这种结果,Django还会针对Referer
标头检查https://
标头(预计始终在Host
个请求中设置)。在上面的示例中,该检查将失败,因为攻击者无法伪造Referer
标头。浏览器会将其设置为攻击者用于托管其恶意表单的http://
页面,Django将检测该页面与其正在服务的https://
端点之间的不匹配。