浏览器是否允许发送跨域请求?

3
我是一个新手,正在尝试深入了解同源策略。虽然stackoverflow和其他地方有非常好的关于SOP概念的文章,但我找不到有关chrome和其他浏览器是否允许跨域XHR post请求在第一时间“发送”的更新信息。
this五年前的帖子中,似乎chrome允许请求通过到请求的服务器,但不允许请求者读取响应。
我在我的网站上进行了测试,试图从不同的域更改我的服务器上的用户信息。详细信息如下:
  1. 我的域名:"www.mysite.com"
  2. 攻击者的域名:"www.attacker.mysite.com"。根据同源策略,这两个被认为是不同的源。
  3. 用户(在登录到www.mysite.com时)打开www.attacker.mysite.com并按下一个按钮,该按钮向“www.mysite.com”服务器发送POST请求...提交的隐藏表单(在此情况下没有令牌)具有更改用户信息所需的所有信息,位于'www.mysite.com'服务器上-->结果:CSRF成功攻击:用户信息确实发生了更改。

  4. 现在使用javascript通过JQuery .post提交表单而不是提交表单-->结果:除了chrome给出正常响应之外:

请求的资源中不存在“Access-Control-Allow-Origin”头

我发现在服务器端没有做任何更改...似乎请求甚至都没有从浏览器传递。用户信息根本没有更改!虽然听起来很好,但我期望相反的结果。

根据我的理解和上面链接的帖子,对于跨域请求,浏览器只应该阻止服务器响应而不是从一开始就发送post请求到服务器。此外,我没有设置任何CORS配置;没有发送Access-Control-Allow-Origin headers。但即使我已经设置了,这也仅适用于“读取”服务器响应,而不是实际发送请求...对吗?
我考虑过预检请求,在此发送请求以检查是否允许在服务器上进行更改用户信息的实际数据之前阻止请求。然而,根据Access_Control_CORS,这些预检请求仅在特定情况下发送,这些情况不适用于我的简单AJAX post请求(其中包括一个默认为application/x-www-form-urlencoded的简单表单,并且未发送自定义标头)。
那么是Chrome已经更改了其安全规范以防止从一开始就向跨域发送post请求呢? 还是我在同源策略方面有所误解?
无论哪种方式,了解不同Web浏览器中实施的更新安全措施的来源将非常有帮助。

但是,攻击者为什么要使用XHR来阻止自己,而不是直接使用表单提交呢? - Neil McGuigan
没错,我只是在探索SOP的极限和它的行为。 - Ahmad Khaled
我刚刚注意到这个问题,本来想在SO上提问,但偶然看到了这篇帖子。 - Sнаđошƒаӽ
2个回答

5
XMLHttpRequest对象的行为随着时间而得到修订。
当SOP(同源策略)引入后,XMLHttpRequest被更新以限制每个跨源请求。
如果URL的起源与XMLHttpRequest的起源不同,则用户代理应引发SECURITY_ERR异常并终止这些步骤。
XMLHttpRequest Level 1open方法中得知上述信息。
初始想法是,无法读取响应的AJAX请求是无用且可能恶意的,因此它们被禁止了。
因此,一般来说,跨域AJAX调用永远不会到达服务器。 这个API现在被称为XMLHttpRequest Level 1
结果证明,SOP总体上太严格了,在CORS开发之前,Microsoft开始提供(并试图标准化)一个新的XMLHttpRequest2 API,该API只允许某些特定的请求,并剥离任何cookie和大多数头文件。
标准化失败后,CORS问世后被合并回XMLHttpRequest API。 Microsoft API的行为大多得以保留,但允许在服务器明确允许时进行更复杂(即潜在危险)的请求(通过使用预检请求)。

非简单头或Content-Type的POST请求被视为复杂请求,因此需要进行预检请求。

预检请求使用OPTIONS方法,并不包含任何表单信息,因此不会对服务器进行更新。
当预检请求失败时,用户代理(浏览器)会终止AJAX请求,保留XMLHttpRequest Level 1的行为。
简而言之,对于XMLHttpRequest,SOP更加严格,拒绝任何跨域操作,尽管SOP原则已经明确了目标。这是可能的,因为当时这并没有破坏任何东西。
CORS放宽了政策,允许默认的“非有害”的请求,并允许协商其他请求。

1
谢谢你提供这么好的概述...你是否考虑分享一下你获取这些信息的资源?了解事物变成现在这个样子的历史背景总是很有趣的。 - Ahmad Khaled
但是,如果跨来源请求者的POST请求被服务器处理(CORS未启用),那么这不算有害吗?服务器的状态已经被一个本不应该具备能力的请求所改变。 - Sнаđошƒаӽ
1
@Sнаđошƒаӽ 是的,那样做是有害的,但 SOP 的目的是防止任何网站从中读取其他网站(因为这将访问来自已验证会话的数据)。您所描述的是 CSFR,可以通过例如表单令牌来避免。网站实施安全策略是由其自行决定的,但 SOP 是必需的,因为网站无法判断一个“读取”请求是否合法。请注意,POST 请求响应无法被读取。请参见 此处 - Margaret Bloom
1
@Sнаđошƒаӽ 关于“为什么要允许POST请求”,我不确定。我认为这是HTTP的设计特性,W3C也有提到类似的内容。可能他们严格关注了主要问题:第三方网站的阅读,并不希望禁止写入。 - Margaret Bloom

2

好的...我明白了...这既不是Chrome浏览器中的新政策,也不是SOP中缺少某些内容...

"www.mysite.com"的会话cookie被设置为"HttpOnly",这意味着,正如这里所提到的那样,它们不会随着AJAX请求一起发送,因此服务器不会更改用户在第4点中的详细信息。

一旦我在我的POST请求中添加了xhrFields: { withCredentials:true },我就能够像预期的那样,在跨域XHR POST调用中更改用户的信息。

虽然这证明了一个已知的事实,即浏览器实际上将跨域POST请求发送到服务器,并仅阻止服务器响应,但对于那些试图深入了解SOP和/或尝试使用CORS的人来说,这仍然可能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接