# 7.浏览器安全

## 32 | 同源策略：为什么XMLHttpRequest不能跨域请求资源？

> 浏览器安全可以分为三大块--Web页面安全、浏览器网络安全、浏览器系统安全。\
> 本节来分析页面中的安全策略。
>
> 在没有安全保障的 Web 世界中，我们是没有隐私的，因此需要安全策略来保障我们的隐私和数据的安全。这就引出了页面中最基础、最核心的安全策略：`同源策略（Same-origin policy）`。

### 什么是同源策略

> 如果两个 URL 的协议、域名和端口都相同，我们就称这两个 URL 同源.\
> 浏览器默认两个相同的源之间是可以相互访问资源和操作 DOM 的。两个不同的源之间若想要相互访问资源或者操作 DOM，那么会有一套基础的安全策略的制约，我们把这称为同源策略。\
> 具体来讲，同源策略主要表现在 DOM、Web 数据和网络这三个层面。
>
> * 第一个：DOM层面。同源策略限制了来自不同源的 JavaScript 脚本对当前 DOM 对象读和写的操作。   &#x20;
> * 第二个：数据层面。同源策略限制了不同源的站点读取当前站点的 Cookie、IndexDB、LocalStorage 等数据。  &#x20;
> * 第三个，网络层面。同源策略限制了通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点。

### 安全和便利性的权衡

> 浏览器出让了同源策略的一些安全性。
>
> #### 1. 页面中可以嵌入第三方资源
>
> 页面中可以嵌入第三方资源，但是却有可能嵌入的是恶意代码，恶意读取Cookie等数据，于是浏览器中引入了内容安全策略，称为CSP。\
> CSP 的核心思想是让服务器决定浏览器能够加载哪些资源，让服务器决定浏览器是否能够执行内联 JavaScript 代码。

#### 2. 跨域资源共享和跨文档消息机制

> 为了解决不同源的资源不能共享问题，引入了`跨域资源共享(CORS)`，使用该机制可以进行跨域访问控制，从而使跨域数据传输得以安全进行。\
> 在介绍同源策略时，我们说明了如果两个页面不是同源的，则无法相互操纵 DOM。不过在实际应用中，经常需要两个不同源的 DOM 之间进行通信，于是浏览器中又引入了跨文档消息机制，可以通过 window\.postMessage 的 JavaScript 接口来和不同源的 DOM 进行通信。

## 33 | 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性？

> 通过上一节我们知道：同源策略可以隔离各个站点之间的 DOM 交互、页面数据和网络通信，虽然严格的同源策略会带来更多的安全，但是也束缚了 Web。这就需要在安全和自由之间找到一个平衡点，所以我们默认页面中可以引用任意第三方资源，然后又引入 CSP 策略来加以限制；默认 XMLHttpRequest 和 Fetch 不能跨站请求资源，然后又通过 CORS 策略来支持其跨域。不过支持页面中的第三方资源引用和 CORS 也带来了很多安全问题，其中最典型的就是 XSS 攻击。

### 什么是XSS攻击

> XSS 全称是 Cross Site Scripting，为了与“CSS”区分开来，故简称 XSS，翻译过来就是“跨站脚本”。XSS 攻击是指黑客往 HTML 文件中或者 DOM 中注入恶意脚本，从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。 恶意脚本可以做哪些事情呢？
>
> * 可以获取Cookie消息。   &#x20;
> * 可以监听用户行为。 &#x20;
> * 可以通过修改DOM伪造假的登录窗口，用来欺骗用户输入用户名和密码等信息。  &#x20;
> * 还可以在页面内生成浮窗广告。

### 恶意脚本是怎么注入的

> 常见的注入方式有：存储型XSS攻击、反射型XSS攻击、基于DOM的XSS攻击。

### 如何阻止XSS攻击

> 1. 服务器对输入脚本进行过滤或转码。  &#x20;
> 2. 充分利用CSP。 &#x20;
> 3. 使用 HttpOnly 属性。

## 34 | CSRF攻击：陌生链接不要点

> 在上一节中我们简单了解了 XSS 攻击，XSS 的攻击方式是黑客往用户的页面中注入恶意脚本，然后再通过恶意脚本将用户页面的数据上传到黑客的服务器上，最后黑客再利用这些数据进行一些恶意操作。XSS 攻击能够带来很大的破坏性，不过另外一种类型的攻击也不容忽视，它就是 CSRF 攻击。

### 什么是CSRF攻击

> CSRF 英文全称是 Cross-site request forgery，所以又称为“跨站请求伪造”，是指黑客引诱用户打开黑客的网站，在黑客的网站中，利用用户的登录状态发起的跨站请求。简单来讲，CSRF 攻击就是黑客利用了用户的登录状态，并通过第三方的站点来做一些坏事。
>
> 黑客有三种方式实施CSRF攻击：
>
> * 自动发起Get请求。  &#x20;
> * 自动发起POST请求。 &#x20;
> * 引诱用户点击链接。 &#x20;
>
> 和 XSS 不同的是，CSRF 攻击不需要将恶意代码注入用户的页面，仅仅是利用服务器的漏洞和用户的登录状态来实施攻击。

### 如何防止CSRF攻击

> 发起 CSRF 攻击的三个必要条件：
>
> * 第一个，目标站点一定要有 CSRF 漏洞；   &#x20;
> * 第二个，用户要登录过目标站点，并且在浏览器上保持有该站点的登录状态；   &#x20;
> * 第三个，需要用户打开一个第三方站点，可以是黑客的站点，也可以是一些论坛。   &#x20;
>
> 要让服务器避免遭受到 CSRF 攻击，通常有以下几种途径:
>
> 1. 充分利用好Cookie的SameSite属性。SameSite选项通常有Strict、Lax、None三个值。   &#x20;
> 2. Strict最为严格，举个例子，黑客从他的网站去去访问你网站的资源，如果你的网站的某些Cookie设置了SamteSite = Strict，那么在黑客网站上的Cookie是不会发送到你的网站上的，只有你从你的站点去请求你站点的资源，才会带上这些Cookie。 &#x20;
> 3. Lax相对宽松，在跨站点的情况下，从第三方站点的链接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie。但如果在第三方站点中使用 Post 方法，或者通过 img、iframe 等标签加载的 URL，这些场景都不会携带 Cookie。&#x20;
> 4. 而如果使用 None 的话，在任何情况下都会发送 Cookie 数据。
> 5. 验证请求的来源站点 服务器可以禁止来自第三方站点的请求。那么该怎么判断请求是否来自第三方站点呢？这里介绍的是HTTP请求头中的Referer和Origin属性。\
>    `Referer`是HTTP请求头中的一个字段，记录了该HTTP请求的来源地址,会包含具体的 URL 路径。\
>    虽然可以通过 Referer 告诉服务器 HTTP 请求的来源，但是有一些场景是不适合将来源 URL 暴露给服务器的，因此浏览器提供给开发者一个选项，可以不用上传 Referer 值，具体可参考 Referrer Policy。\
>    但在服务器端验证请求头中的 Referer 并不是太可靠，因此标准委员会又制定了 `Origin`属性，在一些重要的场合，比如通过 XMLHttpRequest、Fecth 发起跨站请求或者通过 Post 方法发送请求时，都会带上 Origin 属性.\
>    Origin 属性只包含了域名信息，并没有包含具体的 URL 路径.
> 6. CSRF Token\
>    第一步，在浏览器向服务器发起请求时，服务器生成一个 CSRF Token。CSRF Token 其实就是服务器生成的字符串，然后将该字符串植入到返回的页面中。\
>    第二步，在浏览器端如果要发起转账的请求，那么需要带上页面中的 CSRF Token，然后服务器会验证该 Token 是否合法。如果是从第三方站点发出的请求，那么将无法获取到 CSRF Token 的值，所以即使发出了请求，服务器也会因为 CSRF Token 不正确而拒绝请求。

## 35 | 安全沙箱：页面和系统之间的隔离墙

### 安全视角下的多进程架构

> 我们通过学习第一节《宏观视角下的浏览器》，了解了浏览器的发展史以及架构的演变，这节是从操作系统安全的视角来看浏览器的多进程架构的。\
> 浏览器是被划分为`浏览器内核`和`渲染内核`两个核心模块，其中浏览器内核是由网络进程、浏览器主进程和GPU主进程组成的。渲染内核就是渲染进程。这两个模块通过IPC来通信。 浏览器多进程架构的设计不单单是为了增加其稳定性，重要的一点也是因为从安全角度去考虑、设计的。

### 安全沙箱

> 基于安全原因(主要是为防止危险资源获取系统权限)，在渲染进程和操作系统之间建了一道墙，即便渲染进程由于存在漏洞被黑客攻击，但由于这道墙，黑客就获取不到渲染进程之外的任何操作权限。将渲染进程和操作系统隔离的这道墙就是安全沙箱。\
> 浏览器中的安全沙箱是利用操作系统提供的安全技术，让渲染进程在执行过程中无法访问或者修改操作系统中的数据，在渲染进程需要访问系统资源的时候，需要通过浏览器内核来实现，然后将访问的结果通过 IPC 转发给渲染进程。\
> 安全沙箱最小的保护单位是进程。因为单进程浏览器需要频繁访问或者修改操作系统的数据，所以单进程浏览器是无法被安全沙箱保护的，而现代浏览器采用的多进程架构使得安全沙箱可以发挥作用。

## 36 ｜ HTTPS：让数据传输更安全

> 浏览器安全主要分为三大块内容：页面安全、系统安全、网络完全，本节主要学习网络安全。
>
> 我们使用 HTTP 传输的内容很容易被中间人窃取、伪造和篡改，通常我们把这种攻击方式称为中间人攻击。\
> 具体来讲，在将HTTP数据提交给TCP后，数据会经过用户电脑、WIFI路由器、运营商和目标服务器，在这中间的每个环节中，数据都有可能被窃取或篡改。

### 在HTTP协议栈中引入安全层

> ![HTTP VS HTTPS](https://static001.geekbang.org/resource/image/9e/cf/9e99f797de30a15a11b0e4b4c8f810cf.png)\
> 安全层有两个主要的职责：对发起 HTTP 请求的数据进行加密操作和对接收到 HTTP 的内容进行解密操作.\
> 我们知道了安全层最重要的就是加解密，那么接下来我们就利用这个安全层，一步一步实现一个从简单到复杂的 HTTPS 协议。
>
> #### 第一版:使用对称加密
>
> 提到加密，最简单的方式是使用对称加密。所谓对称加密是指加密和解密都使用的是相同的密钥。\
> 将对称加密加到安全层后，实现了第一版的对称加密，但是其中传输的client-random和server-client的过程都是明文，所以黑客其实也是可以拿到并篡改的，因此此数据依然可以破解。
>
> #### 第二版：使用非对称加密
>
> 含义：和对称加密只有一个密钥不同，非对称加密算法有 A、B 两把密钥，如果你用 A 密钥来加密，那么只能使用 B 密钥来解密；反过来，如果你要 B 密钥来加密，那么只能用 A 密钥来解密。
>
> #### 第三版：对称加密和非对称加密搭配使用
>
> 最终选择了一个更加完美的方案，那就是在传输数据阶段依然使用对称加密，但是对称加密的密钥我们采用非对称加密来传输.
>
> #### 第四版：添加数字证书
>
> 为了防止黑客通过DNS劫持将用户目标官网的IP地址进行更换，而需添加数字证书，该证书是服务器向浏览器证明“我”就是“我”。

### 小结

> 由于 HTTP 的明文传输特性，在传输过程中的每一个环节，数据都有可能被窃取或者篡改，这倒逼着我们需要引入加密机制。\
> 于是我们在 HTTP 协议栈的 TCP 和 HTTP 层之间插入了一个安全层，负责数据的加密和解密操作。 我们使用对称加密实现了安全层，但是由于对称加密的密钥需要明文传输，所以我们又将对称加密改造成了非对称加密。\
> 但是非对称加密效率低且不能加密服务器到浏览器端的数据，于是我们又继续改在安全层，采用对称加密的方式加密传输数据和非对称加密的方式来传输密钥，这样我们就解决传输效率和两端数据安全传输的问题。\
> 采用这种方式虽然能保证数据的安全传输，但是依然没办法证明服务器是可靠的，于是又引入了数字证书，数字证书是由 CA 签名过的，所以浏览器能够验证该证书的可靠性。
