1. 移动应用安全的全景图:为什么WAF和JWT会同时出现在一个话题里
字面上看,WAF和JWT是两层完全不同的东西:WAF工作在网络边界,负责拦截恶意流量;JWT是应用层的一种令牌格式,负责身份认证。很多人习惯把它们分开学,做完WAF配置就去做JWT实现,做完JWT就以为自己把移动应用安全搞得差不多了。但实际做移动应用安全测试和防护的时候,这两样东西是纠缠在一起的——一个典型的攻击者根本不会区分什么网络层、应用层,他只会问一个问题:这个App的认证体系能不能被打穿。而认证体系一旦被打穿,WAF再强也拦不住合法令牌下的非法操作;反过来,如果JWT做得很完善但WAF形同虚设,攻击者可以先通过注入类攻击直接拿下后端服务。所以真正做安全的人,视野必须横跨这两层。
这也是我写这篇东西的初衷。最近我在整理一个移动应用的安全加固方案,涉及一个典型的"移动端登录 + 后端API + 管理后台"三段式架构,过程中把WAF绕过的常见手法、JWT token的设计与续签、以及两者之间的衔接问题都重新过了一遍。这篇文章不是教科书式的安全理论综述,而是我在实际项目中遇到的问题、使用的方案、以及踩过之后的教训,尽量用能直接复现的细节来讲。
适合阅读这篇文章的人有三类:第一类是正在做移动应用开发,想把登录认证做得更扎实的后端或客户端工程师;第二类是刚转行做安全测试,想系统理解WAF和JWT到底怎么配合、怎么被攻击的测试人员;第三类是像我一样做全栈或架构,需要自己负责应用整体安全设计的人。无论你是哪一类,我都建议你先放下对"安全就是配个WAF"的刻板印象——移动应用安全的核心问题永远是"你的业务身份体系是否可信",WAF只是外围的栅栏,JWT才是门锁本身。
先给一个整体视角。一个移动App从用户点击登录到请求业务数据,安全链条大致是这样:
- 客户端发起登录请求,经过WAF,到达后端认证服务;
- 认证服务校验用户名密码后签发JWT token,返回给客户端;
- 客户端后续请求在Header里携带JWT token,再经过WAF,到达业务API;
- 业务API先验证JWT的签名和有效期,再执行具体业务逻辑。
任何一个环节出问题,整个链路就不可信了。所以接下来我按照实际工作中处理的顺序来讲:先讲WAF的作用边界和绕过手法,再讲JWT的签发与验证细节,然后讲token续签和登出这两个最容易被忽视的设计死角,最后把两者放在一个完整项目里做一次安全测试的实战复盘。
2. WAF的边界感:它能挡住什么,挡不住什么
WAF全称是Web Application Firewall,名字里带"防火墙"三个字,很多人下意识把它当成一个安全强边界,认为流量过了WAF就安全了。这是移动应用安全里最大的认知误区。WAF本质上是一套规则匹配引擎,它按照预设的规则集去检查HTTP请求的URL、请求头、请求体,发现疑似SQL注入、XSS、命令注入等攻击特征就拦截掉。问题在于,规则引擎永远存在两个短板:一是规则覆盖不全,总有不认识的攻击载荷;二是规则会被各种编码、变形绕过。所以做移动应用安全,第一件事就是搞清楚WAF的能力边界。
2.1 WAF在移动应用架构里的典型部署位置
移动应用和传统PC网站的流量特征有一个明显差异:移动端请求的User-Agent更规整,IP相对集中,请求频率更受设备状态影响。这给WAF的部署和调优带来了一些特殊要求。
我在项目里见到的常见部署方式有几种:
- 云WAF:流量先经过云厂商的WAF节点,再转发到源站。配置简单,但要注意加白名单的问题——很多团队图省事,直接在WAF里把移动端API路径全加了白名单,结果等于没配WAF;
- 自建Nginx + ModSecurity:用开源WAF规则拦截,灵活度高,但规则更新和维护成本高,误报率也更难控制;
- 网关内置WAF模块:很多API网关(比如Kong、APISIX、Spring Cloud Gateway的扩展)自带WAF能力,可以在微服务入口统一做安全校验。
实际选型的时候,我更推荐移动端专用的API走网关内置WAF或自建WAF,而不是一股脑全部交给云WAF。原因是移动端API的流量模型非常固定,且很多请求带签名、加密参数,云WAF默认规则集不一定能正确解码这些参数,反而容易产生误报——把正常业务请求拦了,比被攻击更让人头疼。
2.2 WAF绕过的常见手法与真实案例
WAF绕过是安全测试里的必修课。我结合自己做过的一次移动端API安全测试来说。
当时目标系统是某个App的后端API,前面挂着一套商业WAF。我先做常规探测,发现如下特征:登录接口对参数有基础校验,会拦截包含union select和