Web开发的安全之旅 | 青训营笔记
这是我参加【第四届青训营】笔记创作活动的第10天
网络安全问题很常见,会对用户、公司、程序员(祭天)都造成伤害。因此,了解web开发的安全知识,有效防止网络攻击,对前端工程师来说很有必要。下面,将从两个角度来看web安全。
一、攻击篇
Web安全主要有如下几大分类
- XSS
- CSRF(跨站请求伪造)
- SQL注入
- 命令行注入
- DDos注入
- 流量劫持
(一)、XSS(跨站脚本攻击)
XSS原理:它是指攻击者往web页面或url里插入恶意JavaScript脚本代码且应用程序对用户输入的内容没有过滤,那么当正常用户浏览该页面时,嵌入在web页面的恶意JavaScript脚本代码会被执行,从而达到恶意攻击正常用户的目的。如下图:
产生漏洞的两个条件:
- 盲目信任用户的提交内容。
- 把用户提交的内容转换为DOM并解析。
XSS的特点:
- 通常难以从UI上感知(暗地执行脚本)
- 窃取用户信息(cookie/token)
- 绘制UI(例如弹窗),诱骗用户点击/填写表单
XSS攻击例子如下图:
两个服务端接口submit(用户提交内容,服务端从用户提交的内容中读取conten字段存取到数据库)和render(用来渲染页面,服务器从数据库db中读取content字段返回给浏览器用于生成html)。 无论是从第一个接口写数据,还是第二个接口读数据,都没有对用户提交的信息做过滤。当攻击者将提交一个script标签作为一个content字段提交到服务器端,当服务器渲染该段内容时,会导致html中插入了一个script标签,攻击者也就完成了一次XSS攻击。
XSS的分类:
- 反射型XSS:它是非持久型,参数型的跨站脚本。
- 存储型XSS:它是将脚本代码写进数据库可以永久保存数据,危害最大。
- DOM型XSS:与反射性相似,但是DOM是树形结构,利用DOM标签。
1.存储型XSS攻击-Stored XSS(会被存储到数据库中)
特点:
- 恶意脚本被存在数据中
- 访问页面——>读数据===被攻击
- 危害最大,对全部用户可见
2.反射性XSS攻击——Reflected XSS
特点:
- 不涉及数据库
- 从URL上攻击
3.基于DOM型(DOM-based XSS)
- 不需要服务器的参与
- 恶意攻击的发起+执行,全在浏览器中完成
Reflected XSS vs DOM-based XSS
两者有点类似,但有一个重要的区别:完成注入脚本地方不同
Reflected XSS是在服务端这里注入脚本DOM-based XSS是在浏览器这里注入脚本
4.Mutation-based XSS
- 利用了浏览器渲染DOM的特性(独特优化)
- 不同浏览器,会有区别(按浏览器进行攻击)
如图,如果把<noscript><p title="</noscript><img src=x onerror = alert(1)>"> 进行渲染的话,就会变为第二张图的效果,发现<p title="会作为noscript标签的内容,而<img src=x onerror = alert(1)>会作为正常标签进行渲染,src属性不符合规范,所以会触发onerror事件,回调一触发,完成这种XSS攻击。
(二)、跨站伪造请求(Cross-site request forgery(CSRF))
特点:
1.在用户不知情的前提下
2.利用用户权限
3.构造指定的HTTP请求,窃取或修改用户敏感信息
如上图,用户收到了一封邮件,里面有个链接,他点了一下,去访问了一个恶意的页面,在这个页面中攻击者构建了一个攻击请求,向银行发起一个转账,而这个请求实在另外一个域名,银行服务器(server A)接受到了这个请求,发现请求上有用户的cookie,而且验证通过,认为该请求合法,然后就执行转账操作,完成转账返回结果,最后用户平白无故的丢失了一笔钱。可以发现整个过程,用户没有访问银行的页面,但对应得转账接口却被请求了,且请求成功,这就是跨站伪造请求。
注入(Injection)
SQL Injection
1读取请求字段
2直接以字符串的形式拼接SQL语句
执行以上代码,达成删库跑路成就。
解决方法:
- 正确使用get(只用于查看,列举,展示等不需要改变资源属性的时候) post(用于form表单提交,改变一个资源的属性或做一些其他事情,如数据库增删改)和cookie
- 非GET请求中,为每个用户生产一个cookie token
- POST请求的时候使用验证码
- 渲染表单的时候,为每个表单加一个 csrfToken,然后在后端做 csrfToken验证
- 校验请求来源
- 设置cookie samesite
Injection不止于SQL
- CLI
- OS command
- Sever-Side Request Forgery(SSRF),服务端伪造请求
- 严格而言,SSRF不是injection,但是原理类似。
执行
读取+修改
(三)、服务拒绝(DOS)
概念:通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多的请求,导致请求挤压,进而雪崩效应形成。
插播:正则表达式———贪婪模式
ReDoS:基于正则表达式的DoS
如图,服务器写了一个贪婪的正则表达式,攻击者传入一个容易发生回溯的字符串abababababab...b通过正则试图匹配上ababababababa,第一次发现不行,回溯,又不行,又回溯...这样导致服务器的响应时间大大延长,导致结果吞吐量明显降低,响应用户的次数大大下降。
Logical DoS
耗时的同步操作;数据库写入;SQL join;文件备份;循环执行逻辑
Distributed DoS(DDoS)
概念:短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而形成雪崩效应,无法响应新请求。(不搞复杂的,量大就完事)
攻击特点:直接访问IP;任意API;消耗大量带宽(耗尽)
用于通信的ICMP消息不需要明确的端口号,避免被IDS检测到——TFN2K
哪里阻止DDoS,哪里就受到攻击——防火墙
源IP地址可以伪装,但攻击路径不能伪装——防火墙过滤进出的伪造源IP地址的数据包。所以攻击一旦进行之后,要立即瓦解网络,防止追踪
IP溯源技术只能追踪到攻击者所在的网关
如图,攻击者构造大量的SYN给服务器,服务器会返回ACK,SYN,但攻击者此时不会返回第三次ACK,导致第三次握手未完成,连接数不能被释放,从而很快服务器达到最大连接次数,所有的新请求都无法响应,完成一次洪水攻击。
(四)、基于传输层攻击方式———中间人攻击
二、防御篇
(一)、XXS防御
- 永远不要信任用户提交的内容,即不要直接将用户内容转为动态DOM,而是用String形式储存。
- 当用户应用需求需要使用到动态DOM时间,应该设置逻辑对上传DOM和解析DOM进行转义 /
new DOMOarse()
- 对于svg文件的上传应该尤其的注意防护,svg文件可以内嵌js脚本
<svg><script>alert("xss")</script></svg>
- 尽量不要允许用户自定义跳转(JS)、自定义样式也不行。
现成工具:
前端:主流框架默认防御 XSS;google-closure-library
服务端(Node):DOMPurify
-
同源请求策略:
- 前端请求时应该保证与服务器的安全策略一致。
- 同源请求策略要求网页所在目录与请求接口域名一致,不一致则会发生跨域(CORS安全策略)。
- 对eval+inline script不生效
Content Security Policy(CSP)
哪些源(域名)被认为是安全的;
来自安全源的脚本可以执行,否则直接抛错;
对eval+inline script说NO!
-
服务器响应头部'
Content-Security-Policy:script-src 'self'//同源Content-Security-Policy:script-src 'self' http://domain.com"//支持跨域 -
浏览器meta
(二)、CSRF安全防御
-
通常网络请求有四种防御策略
- if 伪造请求 === 异常来源
- then 限制请求来源
- Origin 同源请求中,不发送GET+HEAD
- Referer
-
CSRF - token防护
-
除了Origin+Referrer 其他判断【请求来自于合法来源】的方式
-
先有页面,后有请求
- if 请求来自合法页面
- then 服务器接受页面请求
- then 服务器可以识别
-
token验证是通过唯一的加密信息码与用户绑定,每次请求都需要将这个加密码随着请求发送到服务器,服务器解密比对信息后判断是否是用户本人操作。
-
token验证码会设置过期时间,避免token泄露。
-
-
CSRF - iframe 攻击
- 当Origin被限制时,攻击者会将请求包在内作为子页面,即可突破同源
-
CSRF 防护
- 避免GET接口和POST接口合并等偷懒行为
- 防护SameSIte Cookie信息泄露,SameSite Cookie依赖于第三方的Cookie请求,需要允许第三方域名采集Cookie.
- 防御CSRF需要注意逐级施加权限限制
Inject Protection
-
SQL防护
- 最小原则:避免使用sudo || root 命令
- 建立ip白名单,拒绝异常rm操作
- 对URL类型参数、域名、IP加逻辑检验,限制异常请求———防范内网被突破
(三)、防御DoS攻击:
-
ReDoS
- 减少允许用户使用正则表达式请求
- 增加校验, 对代码做扫描 +正则性能测试
-
L-DoS
- 限流: 限制流量的异常波动,对于异常IP封锁。
- 并不是非黑即白: 有时候需要请求量超过阈值才能检测出L-DoS
- 分析代码的性能瓶颈:同步调用、串行逻辑、CPU密集操作
-
DDoS
- 过滤:负载均衡、API网关
- 抗量:CDN、快速扩容、 非核心服务降级
(四)、传输层———中间人防御
- HTTP特性: 可靠性-明文加密,完整性:MAC验证;不可抵赖性-数字签名
- HTTPS加密:在三次握手时进行hash加密,利用公钥和证书进行数字签名校验。
- 将HTTP主动升级到HTTPS:需要之前要有一次HTTPS访问
- 当静态资源被劫持篡改了,可以运用SRI对资源做hash验证。
(五)、一点点补充内容
安全无小事
-
使用的依赖(npm package,甚至是Nodejs)可能成为最薄弱的一环
- left-pad事件;
- eslint-scope事件;
- event-stream事件;npm install除了带来黑洞,还可以带来漏洞
- 保持学习的心态
推荐读物