这是我参与「第四届青训营 」笔记创作活动的第3天,主要记录一下几种常见的WEB开发安全问题
攻击篇
XSS 跨站脚本攻击(Cross-Site Scripting)
想方设法将恶意脚本放到我们页面当中·
一些特点:通常难以从UI上感知,窃取用户信息如cookie或token,伪造UI欺骗用户
主要原因:
- 信任用户提交的内容,不进行过滤
- 将用户的内容直接转化为DOM
存储型XSS攻击
特点:
- 恶意脚本存在数据库中
- 访问页面即可因读数据被攻击
- 危害最大(所有用户均可见)
反射性XSS攻击
特点:对服务器进行注入,不涉及数据库,从 URL 上进行攻击
利用query param传递恶意脚本host/path/?param=<script>alert('xss')</script>
public async render(ctx) {
const { param } = ctx.query;
// 直接把用户参数转为 DOM
ctx.body = `<div>${param}</div>`;
}
基于DOM的XSS攻击
特点:对浏览器进行注入,不需要服务器参与,恶意攻击发布和执行在浏览器中完成
同样利用 query param,不过是在浏览器端处理host/path/?param=<script>alert('xss')</script>
const content = new URL(location.href).searchParam.get("param")
const div = document.crateElement("div")
//恶意脚本注入
div.innerHTML = content
document.body.append(div)
基于Mutation的XSS攻击
- 利用浏览器渲染 DOM 的特性 (不同浏览器会有差异)
- 针对不同的浏览器使用不同的攻击手段
- 例子:
<noscript><p title="</noscript><img src="xxx" />">,不易被防御 - img标签的src属性是个随意的字符串,onerror就会触发,XSS攻击成功
CSRF 跨站伪造请求(Cross-site request forgery)
在用户不知情的情况下,利用用户权限(cookie),构造指定HTTP请求,窃取或修改用户敏感信息。
所以所有未知的链接一定要慎点,即使想着只是点进去看看不乱点,也有可能在不知情的情况下被窃取信息访问其他服务器。
CSRF-GET
下面这个图,第一个是主动请求的链接,需要用户点击,而第二个是创建了一个看不到的img标签,src的属性恶意请求,从而大袋用户一访问页面就会发送请求的目的。
更改密码操作的一个Url,在用户不知情的情况下点击,将用户信息更改为我们设定的信息,达到窃取的目的
CSRF-POST
伪造一个表单,将需要更改的信息填入,并hidden,表单提交为post方式,目标站点为更改账户信息的网站,用户点击提交时,顺带将我们更改过的信息提交网站完成窃取。
Injection
SQL注入
流程:请求SQL语句>服务器运行SQL语句>被恶意增删改查数据
CLI
CLI 注入指的是直接拼接 CLI 命令和用户提供的参数,导致用户参数中的恶意命令得到执行。
- 通过
rm -rf删除重要文件 - 读取或修改重要文件
- /etc/passwd
- /etc/shadow
- ~/.ssh
- /etc/nginx/nginx.conf
SSRF服务端伪造请求
从外网访问到其无法访问的内部系统
DoS 服务器拒绝
通过某种方式,导致服务器被显著消耗,来不及响应更多请求导致请求挤压,进而雪崩效应。
ReDoS 基于正则表达式的DoS
使用「 ? 」,使用即为满足一个即可,否则为贪婪模式
左边的正则匹配不到下面的字符串,进行回溯减少匹配的长度,知道最后依旧找不到,响应时间大大提高
Logical DoS
开发者编写的一些不合理的代码或一些不合理的需求,也会导致服务器资源被大量消耗、接口响应时间变长,比如:
- 耗时的同步操作
- 数据库写入
- SQL join
- 文件备份
- 循环执行逻辑
Distributed DoS(DDoS)
短时间内来自大量僵尸设备的请求流量,服务器不能及时完后才能全部请求,导致1请求堆积进而雪崩效应,无法响应新请求。
攻击特点:①直接访问IP;②任意API;③消耗大量带宽。
TCP 与服务器握手三次,在握手第二次后,攻击者并没有进行第三次握手,导致服务器的连接数被占用,当占用到最大连接数时,服务器则无法响应新的请求
传输层 中间人攻击
在浏览器-服务器中插入中间人使得传输层变为浏览器-中间人-服务器,让浏览器认为自己在与服务器沟通,服务器也在与浏览器沟通,中间人则可以继续窃取信息、修改请求和返回数据等等操作
防御篇
XSS
- 永远不信任用户的提交内容;
- 不将用户提交内容直接转换为DOM;
- 对内容(string、svg等等)进行转义;
- 前端主流框架默认防御XSS
内容安全策略(CSP)
- 判断哪些源(域名)是安全的;
- 来自安全源的脚本可以执行否则抛错;
- 禁用 eval 和 行内 Script
CSRF的防御
-
限制请求来源
- 校验
Origin和Referer - 先访问过页面,才接受请求
- 使用与用户绑定的 token,并设置过期时间
- 校验
-
X-Frame-Options: DENY/SAMEORIGIN -
不要在一个接口内既返回数据又修改数据
-
SameSite Cookie
-
Node 中间件
Injection的防御
使用prepared提前将SQL语句提前编译一遍,这样的话在传入查询参数的时候,就可以依赖数据库自带的特性防御注入攻击
DoS的防御
基本是运维的同学去防御,开发基本不做
基于正则表达式的 DoS
- 杜绝写出贪婪模式
- 代码扫描和正则性能测试
- 拒绝使用用户提供的正则表达式
分布式拒绝服务攻击
传输层 中间人攻击
使用HTTPS
- 可靠性:加密
- 传输内容:加密信息 + 加密信息_hash
- 完整性:MAC 验证
- 不可抵赖性:数字签名
TLS 过程
-
非对称加密
- 加密套件选项传给服务端
- 采用套件 + 证书返回给浏览器
- 判断证书正确后协商加密算法生成 sessionKey
-
对称加密
- 通过传输 sessionKey 以及数据进行验证和传输数据
HSTS
通过HSTS使得HTTP主动升级为HTTPS
SRI
通过对比hash判断静态资源是否被劫持