web开发的安全之旅| 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的第7天 与大家分享Web开发的安全之旅,关于web开发的安全问题与防御措施,不足之处欢迎大家批评指正!
web安全总览
安全问题的危害
- 用户
- 公司
- 程序员
举例
Steam免费充值的功能
很遗憾,这个免费充值的功能下线了
攻击篇
XSS
介绍
- 定义
注入恶意脚本,用户隐私泄露
- 原因
①盲目信任用户提交的内容
②直接把用户提交的字符串转化
3.特点
①难以从UI上感知
②窃取用户信息(cookie/token)
③绘制UI(例如弹窗),诱骗用户点击/填写表单
4.XSS demo
▲ 没有过滤!!!▲
写数据/读数据
可以直接提交恶意脚本
分类
1.存储型XSS攻击(Stored XSS)
- 定义
①恶意脚本被存在数据库中
②访问页面 -> 读数据 --- 被攻击
③危害最大,对全部用户可见
例子
2.反射性XSS攻击(Reflected XSS Demo)
- 定义
①不涉及数据库
②从URL上攻击
- 例子
3.基于DOM的XSS攻击(DOM-based XSS)
- 定义
①不需要服务器的提醒
②恶意攻击的发起 + 执行,全在浏览器完成
- 例子
▲ 与Reflected XSS区别:完成注入脚本的地方 ▲
反射性:服务端注入
DOM:服务器端完成闭环
4.基于Mutation-based的XSS攻击(Mutation-based XSS)
- 定义 1.利用了浏览器渲染DOM的特性(独特优化) 2.不同浏览器,会有区别(按浏览器进行攻击)
浏览器端的渲染机制不同,可以理解为基于浏览器的攻击,最难防御
- 例子
CSRF跨站请求伪造(Cross-site request forgery)
定义
1.在用户不知情的前提下 2.利用用户权限(cookie) 3.构造指定HTTP请求,窃取或修改用户敏感信息
例子
1.用户没有访问银行页面
2.银行页面中的特定接口被请求
3.请求执行成功
分类
1.CSRF-GET
用户只要一点击链接,就会完成一次跨站伪造请求
2.CSRF-beyond GET
构造POST请求的表单
Injection注入攻击
分类
1.最常见:SQL Injection
- 示意图
- 例子一 1.读取请求字段
2.直接以字符串的形式拼接SQL语句
2.CLI
3.OS Command
4.服务器端伪造请求(Server-Side Request Forgery)SSRF
严格而言,SSRF不是Injection,但原理类似
- 例子二——读取+修改 1.流量转发到真实第三方
2.第三方扛不住新增流量
3.第三方服务崩溃
4.竞争对手下线
- 例子三——SSRF 1.请求[用户自定义]的callback URL
2.Web Server通常有内网访问权限
Dos攻击
- 定义
通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应
正则表达式——贪婪模式
1.有多少匹配多少
2.有一个就行
ReDos:基于正则表达式的DOS
贪婪:n次不行?n-1次再试试——回溯
响应时间++
接口吞吐量++
Logical DoS
- 定义 1.耗时的同步操作
2.数据库写入
3.SQL join
4.文件备份
5.循环执行逻辑 -例子
DDos
-
定义 短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,造成请求堆积,进而雪崩效应,无法响应新请求
-
攻击特点 1.直接访问IP
2.任意API
3.消耗大量带宽(耗尽)
- 例子
中间人攻击
定义
原因
- 明文传输
- 信息篡改不可知
- 对方身份未验证
防御篇
防御XSS攻击
方法
永远不信任用户的提交内容
!不要将用户提交内容直接转换成DOM!
防御XSS现成工具
- 前端 主流框架默认防御XSS
google-closure-library
- 服务端(Node) DOMPurify
特殊请求:用户必须要动态生成DOM
1.string -> DOM:必须进行转义
2.上传svg -> 对svg文件进行扫描
3.过滤允许自定义跳转链接
4.留意用户自定义样式
小插曲:同源策略Same-origin Policy
- 判断是否同源
协议、域名、端口号均同
- 例子
①
http://example.com
②https://example.com
③https://sub.example.com
上述两者之间均不是同源,①和②协议不同,②和③域名不同
- 对于HTTP请求:一般同源可以,跨域不行,要看请求类型、服务器的设置
Content Security Policy CSP
定义
①哪些源(域名)被认为是安全的
②来自安全源的脚本可以执行,否则直接抛错
③对eval+inline script说no --> 直接拒绝/报错
举例
- 服务器的响应头部
- 浏览器meta
CSRF的防御
定义
防御CSRF-token
- 如何防御
先有页面,后有请求
- 思路
token需要与用户绑定
token需要有过期时间
CSRF-iframe攻击
同源请求
这样点击按钮显示的是点击内容
防御CSRF anti-pattern
- 原因 GET和POST请求没分开
GET != GET+POST
!GET、POST请求一定要分开!
避免用户信息被携带SameSite Cookie
- 定义
- 例子
-
限制了 1.Cookie Domain 2.用户域名
-
依赖Cookie的第三方服务器怎么办?
如内嵌一个x站服务器,识别不了用户登录态,发不了弹幕QAQ
解决:在服务器端将SameSite的属性标记为none,不对它进行限制
- SameSite vs CORS
SameSite限制条件:映射到页面
CORS:白名单
- 例子
- 发展
首次导航的限制:避免敏感操作跳过二次确认,例如重置密码的链接
防御CSRF的正确方法
方法太多,不能case-by-case地一个个防御,应该写一个中间件防御
防御Injection
1.找到项目中查询SQL的地方
2.使用prepared statement
防御Injection beyond SQL
-
最小权限原则
-
建立允许名单+过滤 白名单机制,只允许指定命令,拒绝高危操作
-
对URL类型参数进行协议、域名、ip等限制 避免攻击者访问内网
防御Dos
防御Regex Dos方法
1.注意正则表达式,不采用(/(ab*)+/)
2.代码扫描+正则性能测试
3.不采用用户提供的正则
防御Logical DOS
防御DDoS
1.流量治理
负载均衡(过滤思路)、API网关(过滤思路)、CDN(抗量思路)
2.快速自动扩容(抗量思路)
3.非核心业务降级(抗量思路)
传输层——防御中间人
- 定义
- HTTPS的一些特性 1.可靠性:加密
明文✖
2.完整性:MAC验证
篡改✖
3.不可抵赖性:数字签名
验证身份✔
- HTTPS过程/TLS过程 此处为TLS 1.2
- HTTPS:完整性
- HTTPS方案 传递内容
接收方
- 数字签名 签名执行者
privateKey自己私有
publicKey公开
例子
- HTTPS——不可抵赖:数字签名
CA:Certificate Authority证书机构
数字签名在HTTPS中的工作
- HTTPS——证书
成也证书,败也证书
当签名算法不够健壮时:签名算法被暴力破解
现在可以相对放心地去使用证书
- HTTP主动升级到HTTPS HTTP Strict-Transport-Security(HSTS)
必须有一次HTTP请求
防御SRI
定义
防止静态资源被篡改
例子
标签hash(原始内容hash) vs 实际内容hash
标签hash(原始内容hash)
实际内容
补充:Feature Policy/Permission Policy
一个页面下,可以使用:
- camera
- microphone
- autoplay 这样,当出现安全性问题时,可以禁用这些功能
总结
- 安全无小事
- 使用的依赖(npm package,甚至是NodeJS)可能成为最薄弱的一环
- left-pad事件
- eslint-scope事件
- event-stream事件
- 保持学习心态