为什么CORS中没有预检用于标准内容类型

时间:2016-09-27 13:28:15

标签: security post cors same-origin-policy preflight

我对CORS POST请求的安全方面感到有点困惑。我知道网上有关于这个主题的信息丢失了,但我找不到我的问题的明确答案。

如果我理解正确,同源策略的目标是防止CSRF攻击,而CORS的目标是在(并且仅当)服务器同意与其他人托管的应用程序共享其数据时启用资源共享网站(起源)。

HTTP指定POST请求不是“安全的”,即它们可能会改变服务器的状态,例如:添加新评论。当使用HTTP方法POST发起CORS请求时,如果请求的内容类型是非标准的(或者如果存在非标准的http标头),则浏览器仅执行“安全”预检请求。因此,执行带有标准内容类型和标准标头的POST请求,并且可能对服务器产生负面影响(尽管请求脚本可能无法访问响应。)

有一种向每个表单添加随机令牌的技术,然后服务器需要将其作为每个非安全'请求的一部分。如果脚本试图伪造请求,则

  1. 没有随机令牌,服务器拒绝请求,或
  2. 它尝试访问定义随机令牌的表单。使用随机令牌的此响应应具有适当的头字段,以便浏览器不会授予恶意脚本访问此响应的权限。同样在这种情况下尝试失败。
  3. 我的结论是,对标准内容类型和标题的伪造POST请求的唯一保护是上述技术(或类似的技术)。对于任何其他非安全'请求,如PUT或DELETE,或带有json内容的POST,使用该技术并不是必需的,因为CORS执行'安全'OPTIONS请求。

    为什么CORS的作者将这些POST排除在预检请求之外,因此有必要采用上述技术?

1 个答案:

答案 0 :(得分:25)

请参阅CORS - What is the motivation behind introducing preflight requests?及其他答案。

CORS不要求浏览器为application/x-www-form-urlencodedmultipart/form-datatext/plain内容类型进行预检的原因是,如果确实如此,那么CORS会比什么浏览器已经允许(并且CORS的意图不是对没有CORS的情况下的新限制)。

也就是说,使用CORS,您之前可以执行跨域传递的POST请求不会预先检测 - 因为浏览器在CORS存在之前已经允许它们,并且服务器知道它们。因此,CORS不会改变那些“旧”类型的请求。

但在CORS之前,浏览器根本不允许你进行跨域application/json POST,因此服务器可能会认为他们不会接收它们。这就是为什么对于那些类型的“新”请求而不是“旧”请求需要CORS预检的原因 - 为服务器提供预告,这是一种不同的“新”类型的请求,他们必须明确选择支持。