为什么在 CORS 中没有针对标准 content-type 的 POST 请求的预检
Why is there no preflight in CORS for POST requests with standard content-type
我对 CORS POST 请求的安全方面有点困惑。我知道网上关于这个主题的信息丢失了,但我找不到我的问题的明确答案。
如果我理解正确,same-origin 策略的目标是防止 CSRF 攻击,而 CORS 的目标是在(且仅当)服务器同意与共享其数据时启用资源共享在其他站点(来源)上托管的应用程序。
HTTP 指定 POST 请求不是 'safe',即它们可能会更改服务器的状态,例如通过添加新评论。使用 HTTP 方法 POST 发起 CORS 请求时,如果请求的 content-type 为 non-standard(或者如果有 non-standardhttpheaders)。因此 POST 具有标准 content-type 和标准 headers 的请求被执行并且可能对服务器产生负面影响(尽管请求脚本可能无法访问响应。)
有一种技术可以向每个表单添加一个随机标记,然后服务器要求它成为每个非 'safe' 请求的一部分。如果脚本试图伪造请求,它要么
- 没有随机令牌,服务器拒绝请求,或者
- 它尝试访问定义随机标记的表单。这个带有随机令牌的响应应该有适当的头部字段,这样浏览器就不会授予恶意脚本访问这个响应的权限。同样在这种情况下,尝试失败。
我的结论是,唯一可以防止使用标准 content-type 和 headers 伪造 POST 请求的方法是上述技术(或类似技术)。对于任何其他非 'safe' 请求,例如 PUT 或 DELETE,或带有 json-content 的 POST,没有必要使用该技术,因为 CORS 执行 'safe' OPTIONS 请求.
为什么 CORS 的作者排除了这些 POST 预检请求的豁免,因此有必要采用上述技术?
见What is the motivation behind the introduction of preflight CORS requests?。
CORS 不要求浏览器对 application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
内容类型进行预检的原因是,如果它这样做,那将使 CORS 更多比浏览器一直允许的限制要严格(并且 CORS 的目的并不是要对没有 CORS 的情况下已经可能发生的事情施加新的限制)。
也就是说,对于 CORS,POST 您之前可以执行的跨源请求不会进行预检 - 因为在 CORS 存在之前浏览器已经允许它们,并且服务器知道它们。所以 CORS 对那些“旧”类型的请求没有任何改变。
但在 CORS 之前,浏览器根本不允许您进行跨源 application/json
POST,因此服务器可能会认为它们不会收到它们。这就是为什么那些类型的“新”请求而不是“旧”请求需要 CORS 预检的原因——提醒服务器:这是一种不同的“新”请求类型,他们必须明确选择-支持。
我对 CORS POST 请求的安全方面有点困惑。我知道网上关于这个主题的信息丢失了,但我找不到我的问题的明确答案。
如果我理解正确,same-origin 策略的目标是防止 CSRF 攻击,而 CORS 的目标是在(且仅当)服务器同意与共享其数据时启用资源共享在其他站点(来源)上托管的应用程序。
HTTP 指定 POST 请求不是 'safe',即它们可能会更改服务器的状态,例如通过添加新评论。使用 HTTP 方法 POST 发起 CORS 请求时,如果请求的 content-type 为 non-standard(或者如果有 non-standardhttpheaders)。因此 POST 具有标准 content-type 和标准 headers 的请求被执行并且可能对服务器产生负面影响(尽管请求脚本可能无法访问响应。)
有一种技术可以向每个表单添加一个随机标记,然后服务器要求它成为每个非 'safe' 请求的一部分。如果脚本试图伪造请求,它要么
- 没有随机令牌,服务器拒绝请求,或者
- 它尝试访问定义随机标记的表单。这个带有随机令牌的响应应该有适当的头部字段,这样浏览器就不会授予恶意脚本访问这个响应的权限。同样在这种情况下,尝试失败。
我的结论是,唯一可以防止使用标准 content-type 和 headers 伪造 POST 请求的方法是上述技术(或类似技术)。对于任何其他非 'safe' 请求,例如 PUT 或 DELETE,或带有 json-content 的 POST,没有必要使用该技术,因为 CORS 执行 'safe' OPTIONS 请求.
为什么 CORS 的作者排除了这些 POST 预检请求的豁免,因此有必要采用上述技术?
见What is the motivation behind the introduction of preflight CORS requests?。
CORS 不要求浏览器对 application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
内容类型进行预检的原因是,如果它这样做,那将使 CORS 更多比浏览器一直允许的限制要严格(并且 CORS 的目的并不是要对没有 CORS 的情况下已经可能发生的事情施加新的限制)。
也就是说,对于 CORS,POST 您之前可以执行的跨源请求不会进行预检 - 因为在 CORS 存在之前浏览器已经允许它们,并且服务器知道它们。所以 CORS 对那些“旧”类型的请求没有任何改变。
但在 CORS 之前,浏览器根本不允许您进行跨源 application/json
POST,因此服务器可能会认为它们不会收到它们。这就是为什么那些类型的“新”请求而不是“旧”请求需要 CORS 预检的原因——提醒服务器:这是一种不同的“新”请求类型,他们必须明确选择-支持。