54

我试图了解 CORS。据我了解,这是一种在浏览器中实现的安全机制,可以避免对域的任何 AJAX 请求,而不是用户打开的域(在 url 中指定)。

现在,由于这个限制,许多 CORS 被实施以使网站能够进行跨源请求。但根据我的理解,实施 CORS 违背了“同源策略” SOP的安全目的。

CORS 只是为了对要服务的请求服务器提供额外的控制。也许它可以避免垃圾邮件发送者。

来自维基百科

要发起跨域请求,浏览器会发送带有 Origin HTTP 标头的请求。此标头的值是提供该页面的站点。例如,假设 http://www.example-social-network.com上的页面尝试访问 online-personal-calendar.com 中的用户数据。如果用户的浏览器实现了 CORS,则会发送以下请求标头:

来源:http ://www.example-social-network.com

如果 online-personal-calendar.com 允许该请求,它会在其响应中发送一个 Access-Control-Allow-Origin 标头。标头的值指示允许哪些源站点。例如,对上一个请求的响应将包含以下内容:

访问控制允许来源:http ://www.example-social-network.com

如果服务器不允许跨域请求,浏览器将向 example-social-network.com 页面发送错误,而不是 online-personal-calendar.com 响应。

为了允许访问所有页面,服务器可以发送以下响应标头:

访问控制允许来源:*

但是,这可能不适用于需要考虑安全性的情况。

我在这里想念什么?CORS 保护服务器与保护客户端的意图是什么。

4

2 回答 2

129

同源政策

它是什么?

同源策略是浏览器之间标准化的安全措施。“起源”主要是指“域”。它可以防止不同的来源相互交互,以防止诸如跨站请求伪造之类的攻击。

CSRF 攻击如何运作?

浏览器允许网站以 cookie 的形式将信息存储在客户的计算机上。这些 cookie 附有一些信息,例如 cookie 的名称、创建时间、过期时间、设置 cookie 的人员等。cookie 看起来像这样:

Cookie: cookiename=chocolate;  Domain=.bakery.com; Path=/ [//  ;otherDdata]

所以这是一个巧克力饼干,应该可以从http://bakery.com及其所有子域访问。

此 cookie 可能包含一些敏感数据。在这种情况下,该数据是chocolate...... 如您所见,高度敏感。

所以浏览器存储了这个cookie。每当用户向可以访问此 cookie 的域发出请求时,cookie 就会被发送到该域的服务器。快乐的服务器。

这是一件好事。服务器在客户端存储和检索信息的超酷方式。

但问题是这允许http://malicious-site.com在用户不知情的情况下将这些 cookie 发送到http://bakery.com !例如,考虑以下场景:

# malicious-site.com/attackpage

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://bakery.com/order/new?deliveryAddress="address of malicious user"');
xhr.send();

如果你访问恶意网站,上面的代码执行,并且没有同源策略,恶意用户会代表你下订单,并在他的地方下订单......你可能不喜欢这样.

发生这种情况是因为您的浏览器将您的巧克力 cookie 发送到http://bakery.com,这使http://bakery.com认为您在知情的情况下提出了新订单的请求。但你不是。

简单来说,这就是 CSRF 攻击。跨站点发出伪造请求。“跨站点请求伪造”。由于同源政策,它不会起作用。

同源策略如何解决这个问题?

它阻止恶意站点.com 向其他域发出请求。简单的。

换句话说,浏览器不允许任何站点向任何其他站点发出请求。它将防止不同来源通过此类请求(如 AJAX)相互交互。

但是,从其他主机(如图像、脚本、样式表、iframe、表单提交等)加载资源不受此限制。我们需要另一堵墙来保护我们的面包店免受恶意网站的攻击,使用CSRF 令牌

CSRF 代币

如前所述,恶意站点仍然可以在不违反同源策略的情况下执行以下操作:

<img src='http://bakery.com/order/new?deliveryAddress="address of malicious user"'/>

并且浏览器将尝试从该 url 加载图像,从而导致对该 url 发送所有 cookie 的 GET 请求。为了阻止这种情况发生,我们需要一些服务器端保护。

基本上,我们将一个随机的、具有适当熵的唯一令牌附加到用户的会话中,将其存储在服务器上,并通过表单将其发送给客户端。提交表单时,客户端会将该令牌与请求一起发送,服务器会验证该令牌是否有效。

现在我们已经这样做了,恶意网站再次发送请求,它总是会失败,因为恶意网站没有可行的方法知道用户会话的令牌。


CORS

当需要跨站点请求时,可以绕过该策略。这称为CORS。跨域资源共享。

这是通过让“域”告诉浏览器冷静并允许此类请求来实现的。这个“告诉”的事情可以通过传递一个标题来完成。就像是:

Access-Control-Allow-Origin: //comma separated allowed origins list, or just *

因此,如果http://bakery.com将此标头传递给浏览器,并且创建对http://bakery.com的请求的页面存在于原始列表中,那么浏览器将放开请求以及 cookie .

有一些规则可以根据这些规则定义原点1。例如,同一个域的不同端口不是同一个源。因此,如果端口不同,浏览器可能会拒绝此请求。与往常一样,我们亲爱的 Internet Explorer 是个例外。IE 以相同的方式处理所有端口。这是非标准的没有其他浏览器以这种方式运行。不要依赖这个


JSONP

当 CORS 不是一个选项时,带有 Padding的 JSON 只是一种规避同源策略的方法。这是有风险的,也是不好的做法。避免使用这个。

该技术涉及的是向其他服务器发出请求,如下所示:

<script src="http://badbakery.com/jsonpurl?callback=cake"></script>

由于同源策略不会阻止这2 个请求,因此该请求的响应将被加载到页面中。

这个 url 很可能会响应 JSON 内容。但是仅仅在页面上包含 JSON 内容并没有帮助。当然,这会导致错误。因此http://badbakery.com接受一个回调参数,并修改 JSON 数据,将其包装在传递给回调参数的任何内容中发送。

所以与其返回,

{ user: "vuln", acc: "B4D455" }

这是无效的 JavaScript 抛出错误,它会返回,

cake({user: "vuln", acc:"B4D455"});

这是有效的 JavaScript,它会被执行,并且可能会根据cake函数存储在某个地方,以便页面上的其余 JavaScript 可以使用数据。

这主要由 API 用于将数据发送到其他域。同样,这是一种不好的做法,可能有风险,应该严格避免。

为什么 JSONP 不好?

首先,它非常有限。如果请求失败,您将无法处理任何错误(至少不是以理智的方式)。您无法重试请求等。

它还要求您cake全局范围内拥有一个不是很好的功能。如果您需要使用不同的回调执行多个 JSONP 请求,请让厨师为您节省。这可以通过各种库的临时函数来解决,但仍然是一种骇人听闻的方式。

最后,您将在 DOM 中插入随机 JavaScript 代码。如果您不能 100% 确定远程服务会返回安全的蛋糕,那么您不能依赖这个。


参考

1. https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Definition_of_an_origin

2. https://www.w3.org/Security/wiki/Same_Origin_Policy#Details

其他值得一读

http://scarybeastsecurity.blogspot.dk/2009/12/generic-cross-browser-cross-domain.html

https://www.rfc-editor.org/rfc/rfc3986(对不起:p)

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

于 2014-12-04T13:06:50.607 回答
11

同源策略 (SOP) 是浏览器通过跨站脚本 (XSS) 防止漏洞而实施的策略。这主要是为了保护服务器,因为在很多情况下服务器可以处理身份验证、cookie、会话等。

跨域资源共享 (CORS) 是为数不多的放松 SOP 的技术之一。因为默认情况下 SOP 是“开启”的,所以在服务器端设置 CORS 将允许通过 XMLHttpRequest 将请求发送到服务器,即使请求是从不同的域发送的。如果您的服务器旨在为来自其他域的请求提供服务(例如,如果您提供 API),这将非常有用。

我希望这能澄清 SOP 和 CORS 之间的区别以及各自的目的。

于 2013-02-04T06:31:37.047 回答