同源策略

同源策略的定义

我们的浏览器出于安全考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。

同源策略的应用

如果没有同源策略,别人就可以轻松的获取我们网站的 cookie 信息, 或是对网页进行DOM操作,可能会造成数据被盗取等后果。

例如,它可以防止互联网上的恶意网站在浏览器中运行 JS 脚本,从第三方网络邮件服务(用户已登录)或公司内网(因没有公共 IP 地址而受到保护,不会被攻击者直接访问)读取数据,并将这些数据转发给攻击者

本域与跨域

同一个协议、主机、端口下的页面属于同一个域(即本域),否则就是跨域。

image-20240125204517169

同主机:表示的是主机名相同,而并不是域名。比如上面的例子,第一个例子的主机名为 store.company.com ,最后一个例子的主机名为 news.company.com ,两个例子的主机名不相同,但是域名均为 company.com ,不同源

如果是以下两个链接进行数据交互,可以通过同源策略的检测,允许交互:

1
2
https://www.angular.cn:80/guide/inputs-outputs
https://www.angular.cn:80/guide/index

而如果是以下这样的链接交互数据,则不能通过同源策略的检测:

1
2
3
http://www.child.a.com/test/index.html 		----失败,域名不同
https://www.a.com/test/index.html ----失败,协议不同
http://www.a.com:8080/test/index.html ----失败,端口号不同

所以就会牵引出一个问题,不同源的数据如何进行交互?

跨域数据交互问题

如何跨域加载资源?

  1. 一些特殊的标签

    <script><img><iframe><link> 等标签可以跨域加载资源

    如:可以通过下面的代码访问其他域下的脚本文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>

    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

    </body>
    </html>

  2. 通过jsonp来实现跨域请求

  3. 通过CORS(跨域资源共享)实现跨域请求

  4. 通过代理实现跨域请求
    我们都知道同源策略是浏览器自带的,那么我们如果要避免同源策略进行跨域请求,我们可以通过代理服务器的方式进行请求,例如我们请求一个与自身不同域的脚本文件,那么我们可以先请求与自身同域的一个 url ,然后通过代理服务器进行跳转, 最后返回由代理服务器请求到的脚本文件

详细的例子归纳见:https://blog.csdn.net/l_ppp/article/details/106402136

浏览器第三方插件的同源策略

对于浏览器来说,浏览器加载的一些第三方插件也有各自的同源策略。

最常见的一些插件如Flash、Java Applet、Silverlight、Google Gears等都有自己的控制策略。

浏览器沙箱(sandbox)

以chrome浏览器为例,采用了多进程架构,主要进程包括:浏览器进程、渲染进程、插件进程和拓展进程。插件进程如flash、java、pdf 等与浏览器进程严格隔离,因此不会互相影响。

渲染引擎由Sandbox隔离,网页代码要与浏览器内核进程或操作系统进行通信都需要通过IPC channel,在其中会进行一些安全检查。

Sandbox(沙箱):

  • 原理:Sandbox 的设计目的是为了让不可信任的代码运行在一定的环境中,限制不可信任的代码访问隔离区之外的资源。如果一定要跨越Sandbox边界产生数据交换,则只能通过指定的数据通道,比如经过封装的API来完成,在这些API中会严格检查请求的合法性

  • 应用实例:比如一个提供 hosting服务的共享主机环境,假设支持用户上传PHP、Python、Java等语言的代码,为了防止用户代码破坏系统环境,或者是不同用户之间的代码互相影响,则应该设计一个 Sandbox对用户代码进行隔离。Sandbox需要考虑用户代码针对本地文件系统、内存、数据库、网络的可能请求,可以采用默认拒绝的策略,对于有需要的请求,则可以通过封装API的方式实现。

浏览器所加载的一些第三方插件往往不收sandbox管辖,近年来大部分的浏览器漏洞都是加载第三方插件导致的。

参考资料