这是我参与「第五届青训营」伴学笔记创作活动的第 15 天
关于web安全
安全问题“很常见”,会危害用户的安全、公司的利益,以及程序员的工作
攻击分析
跨站脚本攻击XSS
-
将第三方脚本注入网页,网页运行时执行
-
主要利用
-
开发者盲目信任用户提交内容
-
前端开发者将用户输入直接放到HTML中
document.writeelement.innerHTMLSSR(user_data)
-
-
特点
- 难以从UI上直接感知
- 可以窃取用户信息(包括token, cookie)
- 绘制UI,诱导用户
-
分类
-
存储型xss
- 脚本存在数据库里面
- 只要访问网页,就会执行脚本
- 危害最大,所有用户都会受到攻击
-
反射性xss
- 完全从URL实现攻击
- 将query参数构造成脚本
- 脚本从服务端注入
-
基于DOM的xss
- 不需要服务器参与
- 攻击的发起执行在浏览器中
-
基于mutation的xss
- 利用浏览器渲染DOM的方式攻击
- 不同浏览器结果不一定相同
- 最难防御
-
跨站伪造请求CSRF
-
特点
- 用户不知情
- 利用用户权限如cookie
- 构造指定的HTTP请求,窃取/修改用户信息
-
常见的csrf:get请求
- 可以通过按钮/链接实现
- 也可以通过img等标签,在页面加载时执行
- 只需要构造一个表单即可
注入Injection
-
最常见的注入攻击:SQL注入
- SQL参数放进请求
- SQL代码在服务端运行
- 攻击者通过SQL语句可以对数据库随意修改
-
命令行/OS注入
- 命令行参数放进请求
- 服务端执行命令行代码
- 删除:直接导致服务器宕机
- 读取/修改:暴露重要文件,转发请求(流量攻击)
-
SSRF,严格上不是注入但是很相似
- 请求中加入内网地址
- 服务器运行,攻击者可获取内网信息,操作内网
拒绝服务DoS
-
通过某种方式导致服务器资源显著消耗,来不及响应更多请求,导致请求积压,进而雪崩效应
-
ReDoS基于正则表达式的DoS
- 正则表达式的贪婪模式:没有问号则完全匹配
- 贪婪匹配下回溯行为的出现是根本原因
-
DDoS分布式DoS
- 短时间构造大量来自僵尸设备的请求
- 令服务器无法承受
-
特点:一般访问IP,目的很明确就是流量冲击
基于传输层的中间人攻击
- 中间人可以窃取信息、修改请求
- 中间人可以是浏览器、路由器等
- 主要利用:明文传输、信息篡改不可知、不验证身份
防御分析
XSS防御
-
不要相信用户内容,不要将其生成DOM
-
前端框架一般都提供XSS防御
-
服务端DOMPurify
-
如果用户有这种需求?
- 要对字符串进行转义
- 要对svg文件进行扫描
- 尽量不要让用户自定义跳转链接
- 自定义样式小心url请求
CSP内容安全策略
- 同源策略:同一协议,同一域名,同一端口
- 定义安全源,其它将被拒绝,可以拒绝eval和内联script标签
CSRF防御
-
限制请求来源
origin、referer -
token机制
- 浏览器发页面请求,服务器返回页面和token,浏览器访问api的时候需要带上token供服务器检验
- token需要和具体用户绑定,避免盗用
- token需要过期时间
-
针对iframe的同源请求会被允许,利用HTTP响应头部防御:
X-Frame-Options: DENY/SAMEORIGIN -
CSRF反格式,对于既可以POST也可以GET的请求,攻击者可以获取更多的信息:开发者需要注意区分
-
避免用户信息被携带
- samesite cookie,请求时只允许第一方cookie,限制cookie的domain
- 服务器端
Set-Cookie: Samesite=None; Secure; - 比较:CORS针对资源读写和HTTP请求过滤,资源域名和页面域名,相当于白名单
-
做个中间件,集成CSRF防御
注入防御
- 寻找项目查询SQL的地方,使用prepared statement
- 最小权限原则:所有命令不要通过sudo
- 白名单:只允许指定命令
- 对URL参数类型限制,防止访问内网
DoS防御
-
避免贪婪匹配的正则表达式的出现
-
拒绝用户提供的正则
-
DDoS防御
- 流量治理:过滤,前置CDN
- 快速自动扩容
- 非核心服务降级
传输层防御
- HTTPS
- 可靠性:加密(对称加密+非对称加密)
- 完整性:MAC校验(hash校验)
- 不可抵赖性:数字签名(签名执行者用私钥进行数学计算,生成签名,访问者浏览器通过公钥检验)
- HSTS首次访问https后,将之后一段时间的HTTP升级到HTTPS
- SRI:比较hash,避免数据在CDN被修改
补充内容
-
feature policy
- 限制敏感权限的访问
- iframe中使用allow