HTTP安全之SOP

167 阅读4分钟

SOP,全称为 Same-Origin Policy (同源策略),是浏览器实施的一种十分重要的安全机制。用来限制不同源之间的交互,可以防止恶意网站读取另一个网站的敏感数据。

它可以减少被攻击的媒介。例如,防止互联网上的恶意网站的 JS 脚本,从第三方网络服务或公司内网读取数据,并转发给攻击者。

这个保护策略既然叫同源策略,那就先了解下源是什么。

源是什么?

如果两个 URL 的协议(如HTTP或HTTPS)、端口(如果指定了的话)和主机的都相同时,则这两个 URL 就是同源的。这个方案也被称为“协议/主机/端口元组”,或直接称为“元组”(元组是指一组项目构成的整体)。例如:

  • http://store.company.com/dir/page.htmlhttp://store.company.com/dir2/other.html是同源的,只是路径不同。
  • http://store.company.com/dir/page.htmlhttp://store.company.com/secure.html不同源,协议不同。
  • http://store.company.com/dir/page.htmlhttp://store.company.com:81/dir/etc.html不同源,端口不同(http://默认端口是80)。
  • http://store.company.com/dir/page.htmlhttp://news.company.com/dir/other.html不同源,主机不同。

源的继承

源的继承是指当一个文档或资源加载出另一个文档或资源时,如何确定新加载的内容的源。这对保护Web的安全性至关重要。

iframe中的源继承

当一个页面中包含另一个页面(如通过 <iframe> 标签),每个页面都有自己独立的源。这表示:

  • 主页面和嵌入页面:即使主页面和嵌入页面来自同一个网站,只要其中任何一部分(协议、域名或端口)不同,就会被看做不同的源。
  • 访问受限:根据同源策略,主页面是无法直接访问嵌入页面的 DOM 内容,反之亦然。除非有设置 CORS 头或其他方式来进行安全访问。

加载中的源继承

当一个文档加载另一个新文档时,新加载的会继承上一个文档的源,除非该文档明确指定了其他源。如:

  • 通过<script>标签来加载JavaScript文件:通过脚本来执行时,会加载它文档的上下文来运行,所以它会与加载它的文档是同一个源。
  • 通过<img><link><style>标签来加载外部资源:这些资源通常不会修改当前文档的源,但它们可能会受 CORS 影响。

特殊情况

data:URLs-: 当通过data:URL来加载文档时, 会创建一个全新的、空的安全上下文,不会和其他任何文档共享源。 about:blank和JavaScript:URLS- :这些类型的URL在默认情况下会继承打开它们的文档的源。但可以通过 document.open() 方法来重新设置文档的源。

跨源资源访问

同源策略控制着不同域之间的交互,例如使用XMLHttpRequest<img> 来访问其他域资源的时候,会受到同源策略的影响。

而这些交互通常分为三类:

  • 跨源写操作:一般来说是被允许的,如链接、重定向和表单提交。只有少数的 HTTP 请求需要发送预检请求。
  • 跨源资源嵌入:像利用<script><link><img>等标签将其他域的资源嵌入到当前域中的页面上。这种行为一般是被允许的。
  • 跨源读操作:这个操作一般是不被允许的,毕竟如果随意让其他域的页面读取数据,很容易造成数据泄露。当可以通过内嵌资源来巧妙地读取访问。

那该如何进行跨源资源访问?这就需要用到 CORS(跨域资源访问) 来进行。它是 HTTP 的一部分,允许服务器端来制定哪些主机可以访问。(这里先简单了解,以后会详细介绍)

既然有允许,那就有阻止。那我们又该如何阻止跨域访问?那就是阻止上文中提到的三种交互。

  • 阻止跨源修改:只需要检测请求中的 跨站请求伪造令牌,并使用这个令牌阻止。因为每个合法的请求都包含一个随机生成的、唯一的令牌,到达服务器时进行令牌匹配,不匹配的就直接拒绝。
  • 阻止跨源读取:可以通过设置 CORS 响应头来决定哪些域可以访问。
  • 阻止跨源嵌入:可以使用Content-Security-Policy(CSP)的frame-ancestors指令来决定是否嵌入。

总结

同源策略是Web安全的重要组成部分,它负责掌管不同域之间的交互,能有效的保护敏感数据,保护浏览器的安全使用。但我们可以通过 CORS ,在保证安全的情况下实现跨域访问。了解并理解这些相关技术,对构建安全的Web应用至关重要。