GET 和 POST 请求都容易受到 CSRF 的攻击吗?我们应该改用 PUT 吗?
GET 和 POST 请求易受 CSRF 攻击?
是的,GET 和 POST 都容易受到 CSRF 的攻击。
然而,RFC 7231指出
GET 和 HEAD 方法不应该具有采取除检索之外的操作的意义。这些方法应该被认为是“安全的”。
因此,如果一个网站保持标准并且只将“不安全”的操作作为 POST 来实现,那么这里只有 POST 请求是易受攻击的。然而,许多网站并没有为他们所有的“不安全”行为都这样做——例如,注销功能经常被忽视(尽管这通常被认为是非常低的风险)。
尽管PUT 在没有 CORS 的情况下是安全的,但在大多数情况下它不是正确的使用方法。PUT 是幂等的,因此可以重放请求而不会产生任何后果,而 POST 则不是。并不是说任何浏览器都会任意重试 PUT 请求,但是如果某些 JavaScript 在期望没有进一步状态更改的事件上执行它可能是一个问题,例如。如果您正在实施 CSRF 保护,保护 XHR 请求的一个好方法是在X-Requested-With您的请求中添加一个标头,然后验证此标头服务器端。您可以将其与在服务器端检查的随机值相结合,以在诸如 Flash 之类的浏览器插件包含意外允许标头的漏洞的情况下添加进一步的保护。看到这个答案和这个。
GET和POST都容易受到 CSRF 的攻击,除非服务器设置了强大的Anti-CSRF 机制,服务器不能依赖浏览器来阻止跨域请求。至于 PUT 请求,则略有不同,理论上也是易受攻击的,但需要环境更有利。原因如下:
虽然 GET 和 POST 请求可以通过 HTML 表单、图像、脚本标签等轻松发出,但发出 PUT 请求稍微复杂一些,您无法在没有浏览器干扰请求的情况下发出 PUT请求。
如果您使用 XmlHttpRequest API 将请求方法设置为 PUT,则浏览器首先向目标服务器发送一个CORS(跨源资源共享)“飞行前”请求,基本上寻求发出请求的权限,发生的情况是一个OPTIONS向目标服务器发出请求,标头设置为请求的来源,例如:http ://example.com (托管您的脚本)和Access-Control-Request-Method和Access-Control-Request-Headers。如果服务器以Access-Control-Allow-Origin 响应:http ://example.com,然后浏览器向前发送您的请求。相关地,您需要服务器返回 Origin 标头的值作为您的服务器,如果Origin 标头设置为 '*',则无法随请求发送凭据。由于使用凭据(cookies)向允许Origin: *的服务器发出 PUT 请求是不允许的。来自https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS:
预检请求
与简单请求(上面讨论过)不同,“预检”请求首先通过 OPTIONS 方法向另一个域上的资源发送 HTTP 请求,以确定实际请求是否可以安全发送。跨站点请求是这样预检的,因为它们可能对用户数据有影响。特别是,在以下情况下会预检请求:
它使用 GET、HEAD 或 POST 以外的方法。此外,如果 POST 用于发送 Content-Type 不是 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 的请求数据,例如,如果 POST 请求向服务器发送 XML 有效负载使用 application/xml 或 text/xml,然后预检请求。它在请求中设置自定义标头(例如,请求使用诸如 X-PINGOTHER 之类的标头)
因此,对使用 PUT 的页面进行CSRF 攻击会稍微困难一些,因为它需要目标服务器的配合。但是,这不应该被视为可行的反 CSRF 机制,因为浏览器的怪癖可能会使这种保护机制变得无用。
此外,关于可能导致依赖 PUT 方法作为保护的情况,已在此答案中得到了很好的总结: https ://stackoverflow.com/a/11972282/4399898
希望有帮助。
方法; 即发送、发布、删除、请求、获取等发送数据是无关紧要的。CSRF(跨站点请求伪造)攻击允许 Web 服务器注入和处理不受信任的内容。