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

Isr*_*eca 6 security cors

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

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

到目前为止我找到的最佳答案是:CORS - 引入预检请求背后的动机是什么?问题,但它对我来说仍然有点混乱.

Sil*_*Fox 6

如果Content-Type是'text/plain'或'application/json',为什么重要?

表单支持的三种内容类型(enctype)如下:

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

如果Web服务器上的处理程序接收到表单,并且它不是上述内容类型之一,则可以假定它是发送表单的AJAX请求,而不是HTML <form />标记.

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

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

非常正确.默认情况下,浏览器遵循同源策略.CORS放宽了这个限制,允许另一个Origin读取AJAX的响应.

为什么有飞行前请求?

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

例如,这一直有效.example.comPOST 表格example.org:

<form method="post" action="//example.org/handler.php" />
Run Code Online (Sandbox Code Playgroud)

仅仅检查响应中的"Access-Control-Allow-Cross-Origin-Request:true"标题是否足够?

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

夏天:

HTML表单跨域

  • 只能与某些enctype人一起发送
  • 无法拥有自定义标头
  • 浏览器只会在没有预检的情况下发送它,因为<form>提交的所有内容都是标准的(或者像CORS所说的那样"简单")
  • 如果服务器处理程序从这样的表单接收请求,它将对其进行操作

AJAX交叉起源

  • 只有通过CORS才有可能
  • 某些浏览器的早期版本,如IE 8和9可以发送跨域请求,但不与非标头或enctype
  • 可以enctype完全支持的浏览器中使用自定义标头
  • 为了确保跨源AJAX请求不会欺骗同源AJAX请求(请记住以前不可能使用跨源),如果AJAX请求不简单,那么浏览器将发送预检确保允许这样做
  • 如果服务器处理程序收到一个请求,它将对它进行操作,但只有当它已经通过了预检检查,因为初始请求将使用OPTIONS动词进行,直到浏览器同意服务器正在谈论CORS才会发送实际的GET或POST