这是我参与「第四届青训营 」笔记创作活动的第6天
Web开发的安全之旅
一.攻击篇
1.Cross-Site Scripting(XSS)
- 盲目信任用户的提交内容
- 通常难以从UI上感知(暗地里执行脚本)
- 窃取用户信息(cookie/token)
- 绘制UI(例如弹窗),诱骗用户点击 / 填写表单
public async submit(ctx) {
const { content, id } = cte.request.body;
//没有对content过滤
await db.save({
content,
id
});
}
public async render(ctx) {
const { content } = await db.query({
id:ctx.query.id
})
//没有对content过滤
cctx.body = `<div>${content}</div>`;
}
//在这种情况就可以提交**恶意脚本**。
//<script>xss</script>
Stored XSS
- 恶意脚本被存在数据库中
- 访问页面 - 读数据 === 被攻击
- 危害最大,对全部用户可见
Reflected XSS Demo
- 对url下手脚
- 在服务器端注入
DOM-based XSS Demo
- 对url下手
- 在浏览器中完成
Mutation-based XSS
- 利用浏览器渲染 DOM 的特性(独特优化)
- 不同浏览器,会有区别(按浏览器进行攻击)
<noscript><p title="</noscript><img src=x onerror=alert(1)>"
2.Cross-site request forgery(CSRF)
- 在用户不知情的前提下
- 利用用户权限(cookic)
- 构造指定 HTTP 请求,窃取或修改用户敏感信息
CSRF--GET
<a href="#">点我抽奖</a>
<img style="display:none;" src="#"/>
CSRF--beyond GET
<form action="#" method="POST">
<input name="amount" value="10000000000" type="hidden"/>
<input name="to" value="hacker" type="hidden"/>
</form>
3.Injection
SQL Injection
public async renderForm(ctx) {
const {username,form_id } = ctx,query;
const result = await sql.query(`
SELECT a,b,c FROM table
WHERE username = &{username}
AND form_id = ${form_id}
`);
ctx.body = renderFrom(result);
}
fetch("/api",{
method:"POST",
headers:{
"Content-Type":"application/json"
},
body: JSON.stringify({
username:"any:DROP TABLE table;",
})
})
//删库跑路
Injection 不至于 SQL
-
CLI
-
OS command
-
Server-Side Request Forgery(SSRF),服务器端伪造请求
- 严格而言,SSRF不是 injection ,但原理类似
4.Denial of Service(DoS)
- 通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应。
正则表达式——贪婪模式
const greedyRegExp = /a+/; //有多少匹配多少个 const nonGreedyRegExp = /a+?/; //有一个就行 const str = "aaaaaa"; console.log(str.match(greedyRegExp)[0]); //"aaaaaa" console.log(str.match(nonGreedyRegExp)[0]); //"a"
基于正则表达式的DoS
Distributed DoS(DDoS)
短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而雪崩效应,无法响应新请求。
- 直接访问 IP
- 任意 API
- 消耗大量带宽(耗尽)
5.传输层
中间人攻击:
二.防御篇
1.XSS
-
永远不要信任用户的提交内容
- 不要将用户提交内容直接转换成DOM
现成工具:
前端:主流框架默认防御XSS,google-closure-library
服务器端(Node):DOMPurify
【用户需求】不讲武德,必须动态生成DOM的话:
- 对svg扫描
- 不做用户自定义跳转,如果要需要检查
- 用户自定义样式的话,要对url等地方额外注意
Same-origin Policy 同源策略
- 协议 http/https
- 域名
- 端口
2.Content Security Policy(CSP)
- 哪些源(域名)被认为是安全的
- 来自安全源的脚本可以执行,否则直接抛错
- 对 eval + inline script 说 nonono