浏览器安全分为 Web 页面安全、浏览器网络安全和浏览器系统安全。
1、为什么需要安全策略
假设这样一个场景:你先打开了个银行网站,并登录了,然后不小心打开了个恶意网站,由于没有安全策略,此时恶意网站完全可以对银行网站进行任意操作,比如更改银行网站的 DOM 元素,甚至获取 cookie 等信息,伪造接口请求等,可想而知是很恐怖的。所以在没有安全保障的 Web 世界中,我们是没有隐私的,因此需要安全策略来保障我们的隐私和数据的安全。
2、同源策略
说到安全策略,就不得不提同源策略,那何为同源策略呢?
要理解同源策略,先理解下同源的概念:
如果两个 URL 的协议、域名和端口都相同,我们就称这两个 URL 同源。
比如下面这两个 URL 就属于同源,具有相同的协议 https,相同的域名 juejin.cn,相同的端口
https://juejin.cn/books
https://juejin.cn/events/all
两个不同的源之间若想要相互访问资源或者操作 DOM,那么会有一套基础的安全策略的制约,我们把这称为同源策略。
具体来讲,同源策略主要表现在 DOM、Web 数据和网络这三个层面。
2.1、DOM 层面
同源策略限制了来自不同源的 JavaScript 脚本对当前 DOM 对象读和写的操作。
比如你 window.open 个网站,那么如果该网站与当前网站属于同源,就可以在新打开的网站上操作原网站的 DOM 元素,否则就不可以修改
2.2、Web 数据
同源策略限制了不同源的站点读取当前站点的 Cookie、IndexDB、LocalStorage 等数据
2.3、网络
无法访问跨域的资源
3、安全策略
如果完全采用同源策略,当然是最安全的,但这样会使得 Web 项目难以开发和使用。所以要出让些安全性来满足灵活性,这就是目前的页面安全策略原型。
3.1、页面中可以嵌入第三方资源
同源策略要让一个页面的所有资源都来自于同一个源,也就是要将该页面的所有 HTML 文件、JavaScript 文件、CSS 文件、图片等资源都部署在同一台服务器上,这明显很不合理,比如我要将一些静态资源从 CDN 上获取,就办不到。所以就需要同源策略放[松]下,允许任意引用外部文件。
但因为这个方案,导致页面里会注入恶意的脚本文件,导致 XSS 攻击,后面细讲。
3.2、跨域资源共享
同源策略限制了访问跨域的资源,这会大大制约生产力。所以引进了跨域资源共享(CORS),使用该机制可以进行跨域访问控制,从而使跨域数据传输得以安全进行。
比如响应头部设置如下
access-control-allow-origin: *
3.3、跨文档消息机制
同源策略限制了两个不同源之间的 DOM 操作,但有时需要两个不同源的 DOM 之间进行通信,于是浏览器中又引入了跨文档消息机制。
比如一个页面通过 iframe 嵌入了另一个不同源的页面,此时双方想要进行通信,就得采用 window.postMessage。
4、XSS
由于支持页面中的第三方资源引用和 CORS 带来了很多安全问题,其中最典型的就是 XSS 攻击。
4.1、什么是 XSS
XSS 全称为 Cross Site Scripting ,为了与 CSS 区分开来,所以简称 XSS,翻译过来是跨站脚本。
XSS 攻击是指黑客往 HTML 文件中或者 DOM 中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。
4.2、XSS 攻击的危害
- 窃取 Cookie 信息:恶意脚本通过
document.cookie
的方式获取cookie
信息,并利用 CORS 将 cookie 信息上传到恶意服务器。 - 监听用户行为:使用
addEventListener
接口来监听键盘事件,比如监听用户输入的信用卡等信息,并上传到恶意服务器。 - 修改 DOM:伪造登录窗口,骗取用户输入账号与密码等信息
- 在页面内生成浮窗广告
4.3、XSS 攻击方式
4.3.1、存储型 XSS 攻击
产生存储型 XSS 步骤如下:
- 黑客将带有恶意脚本的表单提交保存到数据库
- 用户请求包含了该脚本的页面
- 用户浏览该页面时,恶意脚本就会将 Cookie 等数据上传到恶意服务器
4.3.2、反射型 XSS 攻击
用户将一段含有恶意代码的请求提交给 Web 服务器,Web 服务器接收到请求时,又将恶意代码反射给了浏览器端。
比如:http://localhost:3000/?xss=<script>alert('你被xss攻击了')</script>
。
黑客经常会通过 QQ 群或者邮件等渠道诱导用户去点击这些恶意链接,所以对于不知来源的链接,要谨慎。
4.3.3、基于 DOM 的 XSS 攻击
基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。
在 Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。
4.4、如何阻止 XSS 攻击
无论是何种类型的 XSS 攻击,它们都有一个共同点,那就是首先往浏览器中注入恶意脚本,然后再通过恶意脚本将用户信息发送至黑客部署的恶意服务器上。
所以要阻止 XSS 攻击,可以通过阻止恶意 JavaScript 脚本的注入和恶意消息的发送来实现。
4.4.1、纯前端渲染
不要采用服务端渲染,而是通过接口请求,然后采用 innerText,setAttribute 等方式设置内容或属性
4.4.2、服务器对输入脚本进行过滤或转码
在服务端将一些关键的字符进行转码,比如 <script
转为 <script>
4.4.3、利用 CSP
CSP 全称为 Content-Security-Policy,翻译过来为内容安全策略
- 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
- 禁止向第三方域提交数据,这样用户数据也不会外泄;
- 禁止执行内联脚本和未授权的脚本;
比如 - 只允许加载本站资源:
Content-Security-Policy: default-src ‘self’
- 只允许加载 HTTPS 协议图片:
Content-Security-Policy: img-src https://*
- 允许加载任何来源框架:
Content-Security-Policy: child-src 'none'
4.4.4、使用 HttpOnly 属性
使用 HttpOnly 标记的 Cookie 只能使用在 HTTP 请求过程中,所以无法通过 JavaScript 来读取这段 Cookie。
5、CSRF
5.1、什么是 CSRF
CSRF 英文全称是 Cross-site request forgery,所以又称为“跨站请求伪造”,是指黑客引诱用户打开黑客的网站,在黑客的网站中,利用用户的登录状态发起的跨站请求。简单来讲,CSRF 攻击就是黑客利用了用户的登录状态,并通过第三方的站点来做一些坏事。
5.2、CSRF 攻击的方式
发起 CSRF 攻击的三个必要条件:
- 目标站点要有 CSRF 漏洞;
- 用户要登录过目标站点,并且在浏览器上保持有该站点的登录状态;
- 需要用户打开一个第三方站点,可以是黑客的站点,也可以是一些论坛。
通常当用户打开了黑客的页面后,黑客有三种方式去实施 CSRF 攻击。 - 自动发起 Get 请求
比如黑客页面有张图片,页面一加载该图片就发起了请求
<img src="xxx">
-
自动发起 POST 请求
构建个隐藏表单,页面加载时触发表单提交
-
引诱用户点击链接
5.3、如何阻止 CSRF 攻击
CSRF 主要是由于服务端的漏洞引起的,所以主要的防护手段是提升服务器的安全性
5.3.1、利用 Cookie 的 SameSite 属性
- Strict 最为严格。如果 SameSite 的值是 Strict,那么浏览器会完全禁止第三方 Cookie。
- Lax 相对宽松一点。在跨站点的情况下,从第三方站点的链接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie。但如果在第三方站点中使用 Post 方法,或者通过 img、iframe 等标签加载的 URL,这些场景都不会携带 Cookie。
- None:在任何情况下都会发送 Cookie 数据。
将一些关键的 Cookie 设置为 Strict 或者 Lax 模式,这样第三方站点发起请求时,这些关键 cookie 就不会带上,从而使得登录验证失败,自然 CSRF 攻击也就无效了。
5.3.2、验证请求的来源站点
攻击都是来自于第三节站点,所以可以通过来源来阻止 CSRF 攻击,那么要如何获取来源呢?
就得采用 HTTP 请求头中的 Referer 和 Origin 属性。
优先判断 Origin,如果请求头中没有包含 Origin 属性,再根据实际情况判断是否使用 Referer 值。
5.3.3、CSRF Token
服务器返回页面时带个标识,调用接口时带上该标识。由于第三方站点无法获取到该标识,所以就算发出了请求,服务端也会因为标识不正确而拒绝请求。
6、相关面试题
- 简明说明下你对同源策略的理解
- 同源与同一站点的区别
- xss 攻击里存储型与反射型攻击的区别
- 如何阻止 xss 攻击
- CSRF 是什么
- 如何阻止 CSRF 攻击
- 谈谈你对 XSS 与 CSRF 两种攻击的理解
- 为什么会有 XSS 与 CSRF 攻击
建议自己先根据上面的内容解答下。
解答:
-
简明说明下你对同源策略的理解:
答:同一协议,同一域名,同一端口的称为同源,同源之间可以进行任意操作,而不同源之间就会有些限制,分为 DOM 、Web 数据和网络三个层面,DOM 上不同源无法修改,无法获取到不同源上的 cookie 等数据,使用 xml 或 fetch 方式无法调用不同源的接口。 -
同源与同一站点的区别
答:同源要求协议、域名以及端口均一样才行;同一站点只要求协议,根域名相同即可,
比如如下两个 URL 就属于同一站点,而不属于同源。
https://shop.example.com
https://www.example.com
-
xss 攻击里存储型与反射型攻击的区别
答:Web 服务器不会存储反射型 XSS 攻击的恶意脚本,这是和存储型 XSS 攻击不同的地方 -
如何阻止 xss 攻击
答:见 4.3 内容 -
CSRF 是什么
答:跨域请求伪造,通过第三方站点模拟用户请求行为 -
如何阻止 CSRF 攻击
答:见 5.3 内容 -
谈谈你对 XSS 与 CSRF 两种攻击的理解
答:XSS 是通过往用户的页面中注入恶意脚本,然后再通过恶意脚本将用户页面的数据上传到黑客的服务器上,最后黑客再利用这些数据进行一些恶意操作。CSRF 攻击不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击。XSS 是利用用户对网站的信任采取攻击的,而 CSRF 是利用网站对用户的信任采取攻击的。 -
为什么会有 XSS 与 CSRF 攻击
答:浏览器为同源策略开的两个“后门”:一个是在页面中可以任意引用第三方资源,另外一个是通过 CORS 策略让 XMLHttpRequest 和 Fetch 去跨域请求资源。