CORS:为什么没有针对Content-Type的POST的飞行前请求:text / plain

时间:2016-09-14 20:01:09

标签: security cors

在阅读了很多关于CORS和飞行前请求之后,我仍然不明白为什么在飞行前有一些例外。如果Content-Type是'text / plain'或'application / json',为什么重要?

如果我做对了,CORS的值是限制返回的数据(它不关心POST是否破坏了数据库,它只关心浏览器无法读取该操作的输出)。但如果这是真的(可能不是)为什么有飞行前请求呢?仅仅在响应中检查“Access-Control-Allow-Cross-Origin-Request:true”这样的标题是不够的?

到目前为止,我在CORS - What is the motivation behind introducing preflight requests?问题中找到了最佳答案,但对我来说仍然有点混乱。

1 个答案:

答案 0 :(得分:5)

  

为什么Content-Type是'text / plain'或者   '应用程序/ JSON'?

三个content types (enctype) supported by a form如下:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

如果Web服务器上的处理程序收到表单,并且它不是上述内容类型之一,则可以假定它是发送表单的AJAX请求,而不是HTML {{1} } tag。

因此,如果现有的CORS前系统使用内容类型作为确保请求不是跨站点的方法以防止Cross-Site Request Forgery (CSRF),那么CORS规范的作者不想要将任何新的安全漏洞引入现有网站。他们通过坚持这样的请求启动预检来确保浏览器和服务器首先兼容CORS。

  

它不关心POST是否破坏了数据库,它只关心它   浏览器无法读取该操作的输出

完全正确。默认情况下,浏览器会遵守Same Origin Policy。 CORS放宽了这个限制,允许另一个Origin读取AJAX的响应。

  

为什么有飞行前请求?

如上所述,为了确保客户端和服务器都兼容CORS,并且不仅仅是发送的HTML表单始终能够跨域提交。

e.g。这一直都有效。 <form />张贴到example.com的表单:

example.org
  

仅仅是不够的   检查像'Access-Control-Allow-Cross-Origin-Request这样的标题:   在回复中是真的吗?

由于CSRF向量。通过检查浏览器是否可以发送预检,它确保在浏览器发送之前授权跨源请求(通过检查CORS响应头)。这使浏览器能够保护当前用户的会话 - 记住这里的攻击者不是运行浏览器的人,受害者在CSRF攻击中运行浏览器,因此操纵的浏览器无法正确检查CORS头或欺骗预检对攻击者自己来说没有任何好处。同样,预检也可以使custom headers等CSRF缓解工作。

夏天:

HTML表单跨域

  • 只能与某些<form method="post" action="//example.org/handler.php" />
  • 一起发送
  • 无法拥有自定义标题
  • 浏览器只会在没有预检的情况下发送它,因为enctype提交的所有内容都是标准的(或"simple",因为CORS会提交)
  • 如果服务器处理程序收到来自此类表单的请求,它将对其采取行动

AJAX跨源

  • 只能通过CORS
  • 某些浏览器的早期版本(如IE 8 & 9)可以发送跨源请求,但不能发送非标准标头或<form>
  • 可以在fully supported browsers
  • 中设置自定义标头和enctype
  • 为了确保跨源AJAX请求不会欺骗同源AJAX请求(请记住以前不可能使用跨源),如果AJAX请求不是simple那么浏览器将发送预检以确保允许此操作
  • 如果服务器处理程序收到请求,它将对其执行操作,但前提是它已通过预检检查,因为初始请求将使用OPTIONS谓词进行,而不是直到浏览器同意服务器正在谈论CORS会发送实际的GET或POST