同源策略 (SOP) 使浏览器阻止脚本从一个来源与另一个来源混淆,除非明确被告知不要这样做。但是仍然允许跨站点 POST,从而为 CSRF 攻击创造了载体。防御是防伪令牌。
但是为什么浏览器开发人员在处理 POST 时不遵循相同的 SOP 理念呢?
同源策略 (SOP) 使浏览器阻止脚本从一个来源与另一个来源混淆,除非明确被告知不要这样做。但是仍然允许跨站点 POST,从而为 CSRF 攻击创造了载体。防御是防伪令牌。
但是为什么浏览器开发人员在处理 POST 时不遵循相同的 SOP 理念呢?
理论上你的建议是完全合理的。如果浏览器默认阻止所有跨源 POST 请求,并且需要 CORS 策略来解锁它们,那么很多所有的 CSRF 漏洞都会神奇地消失。作为开发人员,您只需要确保在 GET 请求上不更改服务器状态。不需要令牌。那样就好了。
但这不是当时互联网的建立方式,现在也无法改变。跨源 POST 请求有许多合法用途。如果浏览器在游戏中途突然改变规则并禁止这样做,那么依赖旧规则的网站就会停止工作。像这样破坏现有网站是我们尽量避免的事情。不幸的是,我们不得不忍受我们的过去。
那么有什么方法可以让系统在不破坏任何东西的情况下更好地工作吗?一种方法是引入一个新的 HTTP 动词,我们称之为 PEST,它就像 POST 一样工作,只是所有 PEST 请求都经过预检并受 CORS 策略的约束。这只是我提出的一个愚蠢的建议,但它显示了我们如何在不破坏标准的情况下制定标准。
问题不在于请求方法:CSRF 也可以通过 GET 请求完成。Authorization
问题在于,跨站点请求中自动包含(会话)cookie 或标头等身份验证信息,从而使 CSRF 成为可能。因此,缓解措施不是禁止在跨站点请求中使用此类方法,而是不发送这些身份验证信息。
对于 cookie,有一个相同站点标志的提议,可以确保 cookie 不会在跨站点请求中发送。不幸的是,该标志目前仅在 Chrome 中可用,但将于 2018 年 5 月在 v60 版 Firefox 中可用。此外,如果默认启用此限制并且需要显式更改以降低安全性(就像在 CORS 中一样)而不是默认不安全。只有这意味着对当前行为的严重改变,并且可能会破坏许多现有的应用程序。
我部分不同意安德斯的观点
但这不是当时互联网的建立方式,现在也无法改变。
主流浏览器的开发者确实有很大的力量来改变互联网并引导 Web 开发者朝着他们想要的方向发展。如果将跨站点 POST 数据视为主要威胁,则它可能会过时。在其他方面也有这样的进展的例子,虽然不是突然也不是很快:
闪光。虽然它以前被视为 Web 的未来,但主要浏览器已宣布将来不再支持它,Web 开发人员正在调整。
HTTPS 已经逐渐被浏览器强制使用,在警告纯 HTTP 不安全方面迈出了一小步。我们最终可能会看到一个普通的 HTTP 慢慢窒息而死的世界。
我希望看到这一点朝着更广泛地优先考虑安全性而不是兼容性的方向发展。自然,如此大的改变不会是一蹴而就的事情,而是先提供替代方案并阻止它。实现这一目标的路径可能是这样的:
POST
,允许明确同意。POST
未经同意,开始在跨站点上显示可能存在安全问题的警告。不鼓励POST
使用纯 HTTP 非常接近不鼓励跨站点POST
,两者都违反标准。这只是有意识地失去向后兼容性,以提高安全性。