javascript客户端设置CSRF token不安全吗?
Is it unsafe for the javascript client to set the CSRF token?
在我看来,CSRF的首要目标是确认发出请求的客户端是我们期望的客户端。
我常见的解决方案是:
- 服务器生成随机 CSRF 令牌
- 服务器在 cookie 中设置 CSRF 令牌
- 服务器在生成表单时将 CSRF 令牌注入到表单中
或者
- 服务器将 CSRF 令牌传递给 javascript 并且 javascript 将 CSRF 令牌作为 header 注入到 XMLHTTPRequests
- 收到请求后,会通过检查 cookie 中的 CSRF 令牌是否与 header/form 值中的 CSRF 令牌相匹配来对其进行验证。
服务器为 (3)(1) 生成 CSRF 对我来说很有意义,但我想不出为什么它对于 (3)(2) 是必要的。
相反,如果客户端是纯 javascript,我相信这是安全的:
- Javascript 生成随机 CSRF 令牌
- Javascript 在 cookie 中设置 CSRF 令牌
- Javascript 在发出 XMLHTTPRequest
时在 header 中传递 CSRF 令牌
- 服务器检查 header 中的 CSRF 令牌是否与 cookie 匹配
我的理解是3和4都是攻击者做不到的,所以这也足以阻止攻击。对吗?
如果 安全,我们还需要执行步骤 (1) 和 (2) 吗?由于 same-origin 策略(假设 cors 配置正确),这是否也安全?
- Javascript 在 XMLHTTPRequest
中设置一个 'CSRF-Safe: true' header
- 服务器检查 header CSRF-Safe 是否存在并设置为 "true"
是的,在 CORS 和 same-origin 策略存在的情况下,这两种简化方法应该是安全的。事实上,只要您验证 content-type.
,您甚至不需要 CSRF-Safe: true
header
维基百科confirms:
If data is sent in any other format (JSON, XML) a standard method is to issue a POST request using XMLHttpRequest with CSRF attacks prevented by SOP and CORS; there is a technique to send arbitrary content from a simple HTML form using ENCTYPE attribute; such a fake request can be distinguished from legitimate ones by text/plain content type, but if this is not enforced on the server, CSRF can be executed[12][13]
在我看来,CSRF的首要目标是确认发出请求的客户端是我们期望的客户端。
我常见的解决方案是:
- 服务器生成随机 CSRF 令牌
- 服务器在 cookie 中设置 CSRF 令牌
- 服务器在生成表单时将 CSRF 令牌注入到表单中 或者
- 服务器将 CSRF 令牌传递给 javascript 并且 javascript 将 CSRF 令牌作为 header 注入到 XMLHTTPRequests
- 收到请求后,会通过检查 cookie 中的 CSRF 令牌是否与 header/form 值中的 CSRF 令牌相匹配来对其进行验证。
服务器为 (3)(1) 生成 CSRF 对我来说很有意义,但我想不出为什么它对于 (3)(2) 是必要的。
相反,如果客户端是纯 javascript,我相信这是安全的:
- Javascript 生成随机 CSRF 令牌
- Javascript 在 cookie 中设置 CSRF 令牌
- Javascript 在发出 XMLHTTPRequest 时在 header 中传递 CSRF 令牌
- 服务器检查 header 中的 CSRF 令牌是否与 cookie 匹配
我的理解是3和4都是攻击者做不到的,所以这也足以阻止攻击。对吗?
如果 安全,我们还需要执行步骤 (1) 和 (2) 吗?由于 same-origin 策略(假设 cors 配置正确),这是否也安全?
- Javascript 在 XMLHTTPRequest 中设置一个 'CSRF-Safe: true' header
- 服务器检查 header CSRF-Safe 是否存在并设置为 "true"
是的,在 CORS 和 same-origin 策略存在的情况下,这两种简化方法应该是安全的。事实上,只要您验证 content-type.
,您甚至不需要CSRF-Safe: true
header
维基百科confirms:
If data is sent in any other format (JSON, XML) a standard method is to issue a POST request using XMLHttpRequest with CSRF attacks prevented by SOP and CORS; there is a technique to send arbitrary content from a simple HTML form using ENCTYPE attribute; such a fake request can be distinguished from legitimate ones by text/plain content type, but if this is not enforced on the server, CSRF can be executed[12][13]