令牌如何防止csrf攻击?

Posted

技术标签:

【中文标题】令牌如何防止csrf攻击?【英文标题】:How to does the token prevent csrf attack? 【发布时间】:2015-09-28 04:17:09 【问题描述】:

我已经阅读了有关 CSRF 以及如何使用不可预测的同步器令牌模式来防止它的信息。我不太明白它是如何工作的。

让我们来看看这个场景:

用户使用此表单登录网站:

<form action="changePassword" method="POST">
   <input type="text" name="password"><br>
   <input type="hidden" name="token" value='asdjkldssdk22332nkadjf' >
</form>

服务器还将令牌存储在会话中。发送请求时,它会将表单数据中的令牌与会话中的令牌进行比较。

当黑客可以编写以下 javascript 代码时,如何防止 CSRF:

    向站点发送 GET 请求 接收包含请求表单的 html 文本。 在 html 文本中搜索 CSRF 令牌。 使用该令牌发出恶意请求。

我错过了什么?

【问题讨论】:

【参考方案1】:

攻击者无法使用 JavaScript 从站点读取令牌,因为这将是一个跨域请求,并且同源策略 (MDN, W3C)。

以此为例:

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://google.com");
xhr.addEventListener('load', function (ev) 
    console.log(this.responseText);  
);
xhr.send();

JS 控制台报告:

XMLHttpRequest 无法加载 http://google.com/。请求的资源上不存在“Access-Control-Allow-Origin”标头。

【讨论】:

值得注意的是,您也可以通过 iframe、脚本或对象标记发出成功的 GET 请求,但浏览器不允许您从 JavaScript(协议、域和端口)获取加载的文档内容必须匹配), 如果有人想知道为什么攻击者不能从站点获取任何旧令牌并在他们的请求中使用它,这是因为该令牌也作为 cookie 存储在攻击者的浏览器中不知道,因此当他使用刚从站点获得的新令牌发送请求时,它与用户 cookie 上的令牌不匹配,因此请求被丢弃。 如果我使用命令行发送请求(例如 CURL 请求),会绕过同源策略吗?【参考方案2】:

认识到 CSRF 攻击只发生在浏览器中很重要。恶意服务器使用用户与目标服务器的会话来伪造请求。那么#1是怎么发生的呢?两种选择:您可以从恶意服务器发出 #1 请求,但这只会为 服务器的 会话返回一个 CSRF 令牌,或者您可以使用 AJAX 发出 #1 请求,正如您正确的那样识别,将返回受害者用户的 CSRF 令牌。

出于这个原因,浏览器已经实现了 HTTP 访问控制。您必须使用 Access-Control-Allow-Origin 标头来限制哪些域可以向您的服务器发出 AJAX 请求。换句话说,您的服务器将确保浏览器不会让恶意站点执行 #1。不幸的是,我读过的关于这个问题的文档不是很清楚,但我认为这是因为服务器默认情况下不会发送Access-Control-Allow-Origin 标头,除非配置为这样做。如果您确实需要允许 AJAX 请求,您必须信任标头中的任何来源不会执行 CSRF 攻击,您可以选择性地锁定应用程序的敏感部分以不允许 AJAX 请求,或者使用其他 Access-Control-* 标头来保护自己。

使用同步器令牌是应用程序可以依赖的一种方式 根据同源策略通过维护秘密来防止 CSRF 用于验证请求的令牌

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

您应该阅读Cross-Origin Resource Sharing (CORS)。

【讨论】:

Access-Control-Allow-Origin 并没有阻止 CSRF,它所做的只是打开了Same Origin Policy 施加的限制。同源策略不会阻止向您的域发出请求,它只是阻止读取响应。 SOP虽然可以阻止同步器token被读取,但它本身对于阻止CSRF是没有用的。 “您必须使用 Access-Control-Allow-Origin 标头” — 否。Access-Control-Allow-Origin 放松安全性。默认情况下它是安全的。如果您希望第三方网站能够读取您的数据,则使用Access-Control-Allow-Origin

以上是关于令牌如何防止csrf攻击?的主要内容,如果未能解决你的问题,请参考以下文章

在隐藏字段中添加反 CSRF 令牌真的可以防止 CSRF 攻击吗? [复制]

Spring Security - CSRF - 如何重置 CSRF 令牌并记录潜在的 CSRF 攻击(OWASP 推荐)

为啥将刷新令牌存储在仅 HTTP 的 Cookie 中以防止 CSRF 攻击?

如何防止 PHP、csrf、xsrf 中的表单重放/中间人攻击

何时需要使用令牌保护表单(CSRF 攻击)?

sql注入,xss攻击,csrf(模拟请求)