浏览器是否允许 cross-domain 请求为 "sent"?

Do browsers allow cross-domain requests to be "sent"?

我是网站安全的新手,目前正试图深入了解 Same-Origin-Policy。 虽然在 Whosebug 和其他地方有很好的 posts 关于 SOP 的概念,但我找不到 updated 关于 chrome 和其他浏览器是否允许 cross-domain XHR post 请求从第一位开始'发送'。

this 5 岁 post 开始,似乎 chrome 允许请求传递到请求的服务器,但不允许请求者读取响应。

我在我的网站上测试过,试图从不同的域更改我服务器上的用户信息。详情如下:

  1. 我的域名:"www.mysite.com"
  2. 攻击者域:"www.attacker.mysite.com" 根据 Same-Origin-Policy 这两个被认为是不同的起源。
  3. 用户(登录到 www.mysite.com)打开 www.attacker.mysite.com 并按下一个按钮,向 'www.mysite.com' 服务器发出 POST 请求。 .提交的隐藏表单(在这种情况下没有令牌)具有更改 'www.mysite.com' 服务器上用户信息所需的所有信息 --> 结果:CSRF 成功攻击:用户信息确实发生了变化。

  4. 现在做同样的事情,但是 javascript 通过 JQuery .post 提交表单而不是提交表单 --> 结果:除了 chrome 给出正常响应:

No 'Access-Control-Allow-Origin' header is present on the requested resource

,我发现服务器端没有做任何更改...似乎请求甚至没有从浏览器通过。用户信息根本没有改变!虽然这听起来不错,但我的预期恰恰相反。

根据我的理解和上面链接的post,对于cross-domain请求,只有服务器响应应该被浏览器阻止,而不是向服务器发送post请求第一名。 另外,我没有设置任何 CORS 配置;没有 Access-Control-Allow-Origin headers 被发送。但即使我有那个设置,那也应该只适用于 'reading' 服务器响应而不是实际发送请求...对吗?

我想到了预检,发送请求以检查服务器是否允许它,从而在发送实际数据以更改用户信息之前阻止请求。但是,根据 Access_Control_CORS ,这些预检仅在特定情况下发送,不适用于我的简单 AJAX post 请求(默认情况下包含带有 enctype 的简单表单 application/x-www-form-urlencoded 并且没有发送自定义 headers。

那么 chrome 是否更改了其安全规范以从一开始就阻止 post 对跨域的请求? 还是我对 same-origin-policy 的理解遗漏了什么?

无论哪种方式,了解是否有在不同网络浏览器中实施的更新安全措施的来源都会很有帮助。

XMLHttpRequest object 行为随着时间的推移而重新审视。

第一个 AJAX 请求不受约束。
引入 SOP 时,更新了 XMLHttpRequest 以限制每个 cross-origin 请求

  1. If the origin of url is not same origin with the XMLHttpRequest origin the user agent should raise a SECURITY_ERR exception and terminate these steps.

来自XMLHttpRequest Level 1,open方法

当时的想法是,无法读取响应的 AJAX 请求是无用的,而且可能是恶意的,因此它们被禁止了。
所以通常 cross-origin AJAX 调用永远不会到达服务器。 此 API 现在称为 XMLHttpRequest Level 1

事实证明,SOP 通常过于严格,在开发 CORS 之前,Microsoft 开始提供(并试图标准化)一个新的 XMLHttpRequest2 API,它只允许一些特定的请求, 被任何 cookie 和大多数 headers 剥离。

标准化失败,在 CORS 出现后被合并回 XMLHttpRequest API。 Microsoft API 的行为大部分被保留,但在服务器的特定允许下(通过使用 pre-flights)允许更复杂(阅读:潜在危险)的请求。

带有 non simple headers or Content-TypePOST 请求被认为是复杂的,因此需要 pre-flight。

Pre-flights 使用 OPTIONS 方法完成,不包含任何表单信息,因此服务器上没有更新。
当 pre-flight 失败时,user-agent(浏览器)终止 AJAX 请求,保留 XMLHttpRequest Level 1 行为。


简而言之:对于 XMLHttpRequest,SOP 更强,尽管 SOP 原则规定了目标,但拒绝任何 cross-origin 操作。这是可能的,因为当时没有破坏任何东西。
CORS 放宽了默认允许 "non harmful" 个请求并允许其他请求协商的策略。

好的...我明白了...这既不是 chrome 中的新政策,也不是 SOP 中遗漏的内容... "www.mysite.com" 的会话 cookie 设置为 "HttpOnly",这意味着,如前所述 here,它们不会与 AJAX 请求一起发送,因此服务器不会t 更改第 (4) 点中的用户详细信息。

一旦我将 xhrFields: { withCredentials:true } 添加到我的 post 请求中,我就能够按预期更改跨域 XHR POST 调用中的用户信息。

虽然这证明了一个众所周知的事实,即浏览器实际上向服务器发送了跨域post请求,并且只是阻止了服务器响应,但对于那些试图加深对SOP and/or 玩 CORS。