这是我参与「第四届青训营 」笔记创作活动的第4天
以下是我在参加此次青训营课程学习中的一些思考及总结。
Web 安全
我们从两个角度来看 web 安全
假如你是一个 hacker -- 攻击
假如你是一个开发者 -- 防御
攻击篇
XSS 简述
跨站脚本攻击(也称为 XSS)指利用网站漏洞从用户那里恶意盗取信息。
XSS 攻击是指黑客通过“HTML注入”篡改网页,插入恶意的脚本,当用户浏览该页之时,嵌入其中 Web 里面的 html 代码会被执行,从而达到恶意用户的特殊目的。
XSS demo
public async submit(ctx) {
const { content, id } = ctx.request.body;
// 没有对 content 过滤
await db.save({
contnet,
id
});
}
public async render(ctx) {
const { content } = await db.query({
id: ctx.query.id
});
// 没有对 content 过滤
ctx.body = `<div>${content}</div>`;
}
XSS 分类
XSS 根据效果可以分为三类:
- 反射型 XSS (Reflected XSS)
反射型 XSS 只有在用户访问恶意链接时,才能攻击成功,反射型 XSS 也叫做非持久型 XSS。
demo
public async render(ctx) {
const { param } = ctx.query;
ctx.status = 200;
ctx.body = `<div>${param}</div>`;
}
- 存储型 XSS
存储型 XSS 会把用户输入的数据存储在服务器端,这种 XSS 具备很强的稳定性。危害最大,对全部用户可见。
- DOM XSS
DOM XSS 与反射型 XSS、存储型 XSS 的主要区别在于 DOM XSS 的 XSS 代码不需要服务端解析响应的直接参与,触发 XSS 的是浏览器端的 DOM 解析。
demo
const content = new URL(location.href).searchParams.get("param");
const div = document.createElement("div");
// 恶意脚本注入
div.innerHTML = content;
document.body.append(div);
XSS 特点
通常难以从 UI 上感知 (暗地执行脚本)
窃取用户信息 (cookie/token)
绘制 UI (例如弹窗),诱骗用户点击/填写表单
CSRF 简述
跨站请求伪造(也称为 CSRF)是一种挟制用户在当前已登录的 Web 上执行非本意的操作的攻击方法。
XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
-
在用户不知情的前提下
-
利用用户权限 (cookie)
-
构造指定 HTTP 请求,窃取或修改用户敏感信息
CSRF demo
防御篇
XSS 防御
永远不要相信用户提交的任何内容
不要将用户提交内容直接转换为 DOM
XSS 现成防御工具
前端
主流框架(React、Vue) 默认防御 XSS
google-closure-library
服务端(Node)
- DOMPurify
【用户需求】必须动态生成 DOM
- string -> DOM
使用 new DOMParser() 类似 API 前必须将字符串进行转译。
- 允许用户上传 svg
提前扫描 svg 标签,防止中间插入 script 脚本恶意代码。
-
Blob 动态生成 script
-
自定义跳转链接
尽量不要让用户自定义跳转行为,如果做也一定要提前过滤。
- 自定义样式
攻击者通过伪造一个 CSS 代码在指定情况下发送一个请求,从而导致攻击。
CSRF 防御
- 限制请求来源
服务器端开发人员可以校验接收的
Origin或者Referer进行校验,如果是当前服务器的域名那么就放行请求,如果不是则拒绝请求。
- token
在服务器接收到一个合法页面请求时,服务器可以通过标识来判断是否是一个合法来源的请求。
- iframe 攻击
限制
Origin,攻击者会使用同源请求来到达攻击。使用
iframe来到达绕过Origin限制达到攻击。
- 避免用户信息被携带 SameSite Cookie
CSRF 的攻击是由于携带了用户
cookie,如果不携带cookie,就从根源上解决了这种 CSRF 攻击。
最后
以上就是我在此次青训营课程 《Web 开发的安全之旅》 中的一些思考和总结。