常见异常调用类型:权限提升、未授权、异常频率与畸形数据
做异常调用检测这几年,我遇到过各种各样的攻击手法。说白了,安全攻防就是一场信息不对等的博弈——攻击者总想用最少的信息撬开最大的口子。而作为防守方,我们得先弄清楚对方手里有几张牌。
异常调用通常可以归为四类。嗯,这四类几乎覆盖了90%以上的API滥用场景。我习惯把它们看作攻击者的四个基本动作:往上爬(权限提升)、翻墙走(未授权访问)、疯狂敲门(异常频率)、丢垃圾数据(畸形调用)。
核心观点: 这四类异常调用不是孤立的,攻击者经常组合使用。比如先通过畸形数据绕过WAF,再发起权限提升调用。检测系统必须能识别这些组合拳。
1. 权限提升调用(Privilege Escalation Calls)
权限提升,说白了就是“普通用户想干管理员的事”。攻击者拿到了一个低权限账号,然后通过篡改请求参数、伪造JWT载荷、利用IDOR(不安全的直接对象引用)等方式,试图访问本不属于他的资源。
我在项目中遇到过最经典的场景:某个电商后台,普通用户能查看自己订单的接口是 /order/{orderId},但攻击者把orderId改成别人的,结果后台没有校验订单归属。这就是典型的水平权限提升。更严重的是垂直权限提升,比如调用 /api/admin/exportAllUsers。
检测要点: 监控请求路径中的敏感关键词(admin、super、root、delete、batch),并结合用户角色进行权限矩阵校验。我建议在API网关层做统一鉴权,而不是让每个微服务自己判断。
你想想看,攻击者往往不会只试一次。他们通常会先试探性访问一个低敏感度的管理员接口,如果返回200,再发起进一步攻击。所以一旦检测到角色与权限不匹配的调用,就要立刻触发告警并阻断。
2. 未授权API调用(Unauthenticated API Calls)
这个和权限提升有点区别:权限提升是有身份但权限不够,未授权是连身份都没有。攻击者直接把请求发到需要认证的接口上,希望某些接口忘记加校验。
我记得有一次给客户做安全审计,发现他们的内部管理后台竟然有3个接口没有加JWT拦截器——迁移代码时漏了。攻击者只要知道IP和端口就能直接调用。你想想看,如果那是数据导出接口,后果不堪设想。
| 区别维度 | 未授权调用 | 权限提升调用 |
|---|---|---|
| 请求是否携带 | 无或无效 | 有效(但权限不足) |
| 检测方式 | 检查认证头是否存在且有效 | RBAC/ABAC权限校验 |
| 常见案例 | 直接调用 /api/v1/users 返回200 | 普通用户调用 /api/v1/admin/users |
| 防御策略 | 网关统一认证拦截 | 服务端二次鉴权 |
注意: 不要完全依赖网关。曾经有一个项目,网关做了认证,但内部RPC调用时服务间没有二次校验,攻击者绕过网关直接访问了内网服务。这要求我们在服务间调用也加一层签名或白名单。
3. 异常频率调用(Abnormal Frequency Calls)
无论是人肉刷票、爬虫还是DDoS,本质上都是频率异常。攻击者在短时间内发起远超正常用户的请求量,破坏服务稳定性甚至窃取数据。
我曾经处理过一个案例:某积分商城,用户每天只能兑换一次。攻击者写了个脚本,每秒发送50次兑换请求。因为系统没有做频率限制,同一账号成功兑换了40次,公司亏了几十万。后来我们增加了滑动窗口限流,才堵住这个窟窿。
检测异常频率,我建议从三个维度看:
- 全局维度: QPS突然飙升,可能刚被刷量。
- 用户维度: 同一用户ID,每秒请求数从1变成100。
- IP维度: 某IP短时间内请求大量不同用户的数据(爬虫特征)。
嗯,这里要注意:设定阈值不能一刀切。比如双十一活动期间,正常用户访问量就是平时的10倍,如果阈值写死就会误伤。我习惯用历史基线动态阈值,比如基于过去7天同时间段的数据,取均值±3σ作为浮动范围。
4. 畸形数据调用(Malformed Data Calls)
这类的攻击手法最多变——SQL注入、命令注入、XSS、JSON解析异常、超长参数、特殊字符绕过等等。攻击者通过构造恶意数据,触发后端解析器或数据库的bug。
最简单的例子:一个登录接口,参数是 username=admin' OR '1'='1。如果后端没有参数化查询,直接拼接SQL,就能绕过认证。我刚开始做安全时,在一个老旧的项目里发现所有查询都是字符串拼接……光这一个漏洞就修了三天。
// 危险代码示例(不要模仿!)
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
ResultSet rs = stmt.executeQuery(sql);
// 安全做法
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
经验之谈: 畸形数据检测不能只靠正则。刚做安全那阵子,我写了一堆正则来拦截SQL注入,结果被各种编码绕过——URL编码、Unicode编码、双写绕过。后来换了基于语法解析的检测引擎(比如SQL parser),误报率才降下来。
除了注入类,还有一类容易被忽略的畸形调用——类型混淆。攻击者把整数字段改成字符串或数组,导致后端反序列化时抛出异常,甚至触发逻辑漏洞。比如一个年龄字段,正常传 25,攻击者传 ["admin", "true"],如果后端没做校验,可能直接覆盖了敏感属性。
我通常把所有输入的校验总结成一句话:信任但要验证。前端可以做校验提升用户体验,但后端必须独立做校验——因为攻击者可以绕过前端直接发请求。
五类异常调用的检测优先级
实际做检测系统时,不可能给所有异常类型同等待遇。我一般按以下优先级排序:
- 权限提升 + 未授权(高危害,检测成本低)
- 畸形数据注入(可能导致数据泄露或RCE)
- 异常频率(常被用于辅助攻击,但单次危害较低)
不过这也要看业务场景。如果是金融系统,未授权调用的优先级最高;如果是社交平台,批量爬取用户信息的异常频率更需要关注。
避坑指南: 我曾经把频率检测的阈值设得特别严格,结果正常用户一天内被限流好几次,产品经理差点找我打架。后来我加了白名单机制——对已知的内部服务IP、爬虫白名单、官方客户端User-Agent,放宽阈值。记住:检测的目标是“异常”,不是“所有非典型行为”。
本章小结
权限提升、未授权调用、异常频率、畸形数据——这四类构成了API安全的主要战场。每个类型都有自己独特的攻击模式和检测难点。我个人的做法是:在网关层先做频率和内容格式的初步过滤,然后把请求日志送入实时分析引擎,利用规则+模型识别权限和未授权问题。你能看到,这套体系的背后其实就两个核心——身份与权限、行为与内容。理解透了,后面设计响应策略时就会游刃有余。