同源策略和CORS(跨域资源共享)
Posted
技术标签:
【中文标题】同源策略和CORS(跨域资源共享)【英文标题】:Same origin Policy and CORS (Cross-origin resource sharing) 【发布时间】:2013-01-18 19:56:37 【问题描述】:我试图理解 CORS。据我了解,这是一种在浏览器中实现的安全机制,可避免对用户打开的域以外的域的任何 AJAX 请求(在 url 中指定)。
现在,由于这个限制,许多 CORS 被实施以使网站能够进行跨源请求。但根据我的理解,实施 CORS 违反了“同源策略”SOP 的安全目的。
CORS 只是为了提供额外的控制来控制服务器想要服务的请求。也许它可以避免垃圾邮件发送者。
来自Wikipedia:
为了发起一个跨域请求,浏览器发送请求 一个 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 保护服务器与保护客户端的意图是什么。
【问题讨论】:
【参考方案1】:同源政策
这是什么?
同源策略是浏览器之间标准化的安全措施。 "origin" 主要指的是一个"domain"。它可以防止不同的来源相互交互,以防止诸如跨站请求伪造之类的攻击。
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 将这些cookies 发送到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 Tokens。
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
带有 Padding 的 JSON 只是一种规避同源策略的方法,当 CORS 不是一个选项时。这是有风险的,也是不好的做法。避免使用它。
这项技术所涉及的是向其他服务器发出请求,如下所示:
<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 不好?
首先,它非常有限。如果请求失败,您将无法处理任何错误(至少不是以理智的方式)。您无法重试请求等。
它还要求您在 global 范围内有一个 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)
【讨论】:
我已尝试对所有一般同源政策问题给出规范的答案。任何建设性的编辑都非常受欢迎:) 您不需要 AJAX 来执行您的deliveryAddress
攻击。除非您首先必须获取 CSRF 保护令牌,否则 img
标记将起作用。另外,JSONP 比使用 CORS 标头的风险更大吗?
@AlexanderO'Mara 正确,我将在答案中添加基于 CSRF 令牌的保护的简要说明。 JSONP 风险更大,因为我们将随机 JavaScript 代码注入页面。如果 API 调用失败,这可能会变得混乱。与XMLHttpRequest
s 不同,一旦发送请求,就没有太多控制权。感谢您的反馈!
同源策略不会阻止您进行跨域请求。它只阻止对跨域请求响应的任何读取访问(参见跨域网络访问:developer.mozilla.org/en-US/docs/Web/Security/…)。换句话说,攻击者仍然可以部署成功的 CSRF 攻击,但他无法读取他的响应攻击
@Stradivari 同源策略确实会阻止您发出跨源请求,但前提是这些请求不是“简单”的(即使用 CORS 时不需要进行预检)。因此 PUT 或 DELETE 将被阻止,但 GET 或 POST 不会执行(但您无法读取响应)。【参考方案2】:
同源策略 (SOP) 是浏览器通过跨站脚本 (XSS) 防止漏洞而实施的策略。这主要是为了保护服务器,因为在很多情况下服务器可以处理身份验证、cookie、会话等。
跨域资源共享 (CORS) 是为数不多的放松 SOP 的技术之一。因为默认情况下 SOP 是“开启”的,所以在服务器端设置 CORS 将允许通过 XMLHttpRequest 将请求发送到服务器,即使请求是从不同的域发送的。如果您的服务器旨在为来自其他域的请求提供服务(例如,如果您提供 API),这将非常有用。
我希望这能澄清 SOP 和 CORS 之间的区别以及各自的用途。
【讨论】:
CORS 是为数不多的放松 SOP 的技术之一。 ==> 在我看来,实现对 CORSin 浏览器的支持会造成漏洞并完全绕过 SOP 提供的安全网 CORS 实际上是在服务器中实现的。当“启用”时,它只是发送一个 HTTP 标头(访问控制允许来源)和响应。浏览器实现了 SOP。如果它没有看到正确的标题,它会阻止响应。 对我来说,CORS 是在错误的服务器中实现的。必须允许禁用 SOP 的唯一服务器是源服务器,而不是发出 ajax 请求的第二个服务器。 我认为 SOP 主要旨在防止的是 CSRF 攻击,而不是 XSS 攻击。以上是关于同源策略和CORS(跨域资源共享)的主要内容,如果未能解决你的问题,请参考以下文章
Python 使用CORS跨域资源共享解决flask服务器跨域问题浏览器同源策略