Web开发的安全之旅
攻击篇
俗话说,“未知攻,焉知防”。所以,让我们先从hacker角度出发,开启web开发安全之旅的攻击篇。了解web常见的攻击方式。
XSS跨站脚本攻击
-
定义
- XSS是Cross-Site Scripting的简称,译为跨站脚本攻击,是一种网页应用程序安全漏洞攻击。攻击者主要通过往网页插入恶意脚本,来达到攻击目的。
-
XSS主要利用了什么达到目的?
- 盲目信任用户提交的内容
- 直接将用户提交的string转化为DOM,如document.write,elementinnerHTML,SSR()
-
XSS特点
- 通常难以从UI上感知到(暗地里执行脚本)
- 窃取用户信息(cookie/session)
- 绘制UI(如弹窗),诱骗用户点击/填写表单
-
XSS demo
如上所示,我们盲目信任用户提交的数据,对用户提交的数据不进行过滤就提交到数据库。此时,如果用户提交的是一个<script>alert('xss')</script>的恶意脚本的话,会直接将这个恶意脚本提交到数据库,并且直接创建于我们的页面中,进而攻击我们的网站,窃取用户信息。
- XSS的类型
-
Stored XSS(存储型XSS攻击)
- 恶意脚本被存放在数据库中
- 访问页面 => 读数据 === 被攻击
- 危害最大,对所有用户可见
-
Reflected XSS(反射型XSS攻击)
- 不涉及数据库
- 从url进行攻击
- 如
path/path?param=<script>alert('xss')</script>,服务器会从用户请求参数中读取片段。
-
DOM-based XSS(基于DOM的XSS攻击)
- 不需要服务器参与
- 恶意攻击的发起和执行,全在浏览器完成。
- demo
let url = 'path/path?param=<script>alert('xss')</script>' let content = url.getParam(param) //获取参数,即`<script>alert('xss')</script>` const div = document.createElemt("div") div.innerHTML = content document.body.append(div) -
Mutation-based XSS(基于Mutataion的XSS攻击)
- 利用了浏览器渲染DOM的特性进行攻击(独特优化)
- 不同的浏览器,会有区别(按浏览器攻击)
- 如
<noscript><p title="</noscript><img src=x onerror=alert(1)>">在很多过滤工具中会把title当成合法的内容,进而在chrome中会被解析为
<noscript><p title="</noscript> <img src="x" onerror="alert(1)"> "">" -
Reflected XSS和DOM-based XSS区别
- 两者在完成脚本注入的地方不同,前者是从服务器把恶意脚本注入到浏览器,而后者是直接就在浏览器中完成恶意脚本注入。
-
CSRF跨站伪造请求
-
定义
- CRSF是Cross-Site Request Forgery的缩写,译为跨站伪造请求攻击。
-
特点
- 在用户不知情的情况下
- 利用用户权限(cookie)
- 构造指定的HTTP请求,进而窃取或修改用户敏感信息。
-
攻击方式
- 构造一个get请求,如a标签,img标签
<a href="https://bank.com/tranfer?to=hacker&amount=1000"></a> <img style="display:none" src="https://bank.com/tranfer?to=hacker&amount=1000"/>- 构造一个post请求表单
<form action="https://bank.com/tranfer" method="post"> <input type="hidden" vulue=""1000000"/> <input type="hidden" vulue=""hacker"/> </form>
Injection注入攻击
- SQL Injection(SQL注入)
- 往请求中恶意注入SQL参数
- 服务器接收请求,解析出SQL语句,运行SQL code
- 获取数据库数据,删除,修改数据
- demo:
读取请求字段,以字符串形式直接拼接SQL语句恭喜你,被动完成了删库跑路的成就!!
- 其他类型
- CLI:命令行界面注入
- OS command:os命令注入,也称shell注入
- SSRF(Server-Site Request Forgery):服务端伪造请求
Denial of Service(DoS)
- 定义
- 通过某种方式,导致服务器资源被显著消耗,来不及相应更多其他请求,导致请求挤压,进而产生雪崩效应。
- 正则表达式--贪婪模式
- 重复匹配时,? 和 no ?:"满足一个即可"vs"尽量多"
const reg1 = /a+/ // 有多少匹配多少
const reg2 = /a+?/ // 只匹配一个
const str = "aaa"
console.log(str.match(reg1)[0]) // aaa
console.log(str.match(reg2)[0]) // a
- ReDos:基于正则表达式的Dos
- 贪婪模式:n次不行,n-1次试试? -- 回溯
- 此时,攻击者传入一个可回溯的字符串,产生的结果就是服务器响应时间被大大延长,接口吞吐量明显降低,响应用户的此时大大下降。
- Distributed Dos(DDos)
- 短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成所有的请求,导致请求堆积,进而产生雪崩效应,无法响应新的请求。简而言之,就是我不跟你搞啥复杂的,量就完事了。
- 特点
- 直接访问IP
- 任意API
- 消耗大量带宽
- DDos demo
SYN Flood 洪水攻击 TCP有三次握手,攻击者会构建大量的TCP请求,发送大量的SYN给服务器,服务器会按照规范返回ACK+SYN并且进入等待状态,但此时,攻击者不返回第三次ACK,导致第三次握手无法完成,服务器连接次数无定法被释放。当服务器达到最大连接数时,新的请求就通通无法被响应,这样就形成了一次洪水攻击。
中间人攻击
- 定义
攻击人在浏览器和服务器之间插入,让浏览器认为自己在跟服务器通信,服务器认为自己在跟浏览器传输数据。而实际上他们都是在跟中间人进行同通信,中间人就可以在中间进行数据窃取和修改等操作。中间人一般可以由路由器,浏览器扮演。
- 原因
- 明文传输
- 信息篡改不可知
- 对方身份为验证
防御篇
讲完攻击篇后,我们大致了解到了几种常见的攻击方式。接下来,就让我们以开发者的角度来学习一下如何进行防御。
XSS防御
- 核心防御理念
- 永远不信任用户提交的内容
- 不要把用户提交内容直接转为DOM
- 现成工具
- 前端
- 主流框架默认防御XSS
- Google-closure-library
- 服务端(Node)
- DOMPurify
- 前端
CRSF防御
- 限制请求来源
- 请求头部Origin具有协议、域名、端口等信息,可以用该字段进行校验
- 请求头部Origin具有协议、域名、端口等信息,可以用该字段进行校验
- 限制头部
- Access-Control-Allow-Origin: *
- token
- 每次请求的时候都携带有token,我们可以通过token进行校验。但token不要存放在cookie中,否则相当于自投罗网。
Injection防御
- 使用代码审查
- 强制使用参数化语句,在运行时将拒绝嵌入用户输入中的SQL语句
Dos防御
- Regex Dos
- code review
- 代码扫描+正则性能测试
- 不使用用户提供的正则使用
- DDos
- 流量治理
- 负载均衡 => 过滤
- API网关 => 过滤
- CDN => 抗量
- 快速自动扩容 => 抗量
- 非核心服务降级 => 抗量
- 流量治理
中间人攻击的防御
- HTTPS
- HTTPS = HTTP + TLS
- 可靠性:进行加密,防止明文传输
- 完整性:MAC验证,防止被篡改
- 不可抵赖性:数字签名,进行身份验证,确保身份合法
- HTTPS = HTTP + TLS