javascript - javascript 客户端设置 CSRF 令牌是否不安全?
问题描述
在我看来,CSRF 的主要目标是确认发出请求的客户端是我们期望的客户端。
我经常看到的解决方案是:
- 服务器生成随机 CSRF Token
- 服务器在 cookie 中设置 CSRF 令牌
- 服务器在生成表单时将 CSRF 令牌注入表单或
- 服务器将 CSRF 令牌传递给 javascript,并且 javascript 将 CSRF 令牌作为 XMLHTTPRequests 上的标头注入
- 收到请求时,通过检查 cookie 中的 CSRF 令牌是否与标头/表单值中的 CSRF 令牌匹配来验证请求。
服务器为 (3)(1) 生成 CSRF 对我来说很有意义,但我无法想出为什么 (3)(2) 需要它的原因。
相反,如果客户端是纯 javascript,我相信这是安全的:
- Javascript 生成随机 CSRF 令牌
- Javascript 在 cookie 中设置 CSRF 令牌
- Javascript 在发出 XMLHTTPRequest 时在标头中传递 CSRF 令牌
- 服务器检查标头和 cookie 中的 CSRF 令牌是否匹配
我的理解是 3 和 4 都是攻击者不能做的事情,所以这也足以阻止攻击。那是对的吗?
如果那是安全的,我们甚至需要执行步骤(1)和(2)吗?由于同源策略(假设 cors 配置正确),这是否也是安全的?
- Javascript 在 XMLHTTPRequest 中设置一个 'CSRF-Safe: true' 标头
- 服务器检查标头 CSRF-Safe 是否存在并设置为“true”
解决方案
是的,在 CORS 和同源策略存在的情况下,这两种简化方法都应该是安全的。CSRF-Safe: true
事实上,只要您验证内容类型,您甚至不需要标题。
维基百科确认:
如果数据以任何其他格式(JSON、XML)发送,标准方法是使用 XMLHttpRequest 发出 POST 请求,并通过 SOP 和 CORS 阻止 CSRF 攻击;有一种技术可以使用 ENCTYPE 属性从简单的 HTML 表单发送任意内容;这样的虚假请求可以通过 text/plain 内容类型与合法请求区分开来,但如果服务器上没有强制执行,则可以执行 CSRF[12][13]
推荐阅读
- typescript - 在 Typescript Mixin 中传递泛型参数
- android - 如何在没有“android:background”的情况下更改加载屏幕颜色?
- vue.js - VueJs在请求axios中获取值输入单选
- sql - 根据另一个表中的条件语句在列中添加值
- amazon-web-services - 无法将我的 AWS EC2 实例连接到我的 GitHub Webhook
- python - 将可能的标志映射到布尔列表有效方法?
- jcs - 只能从本地机器上的 JCS 检索值
- node.js - 在 linux 上如何正确安装 N 节点
- java - 将 super() 从 Java 转换为 Swift
- r - 在 Mac OS 下使用 R 创建绘图