Struts2 漏洞为什么反复出现
Apache Struts2 是 Java Web 框架,其 OGNL 表达式解析机制历史上多次被绕出远程代码执行漏洞,形成 S2-xxx 系列公告;部分漏洞在公开验证代码出现后被大规模扫描与利用。排查重点不是看应用名称或版本号,而是清点实际加载的 struts2-core 等组件版本:war 包内 lib 目录、外层 lib 目录与容器共享库可能同时存在多个版本,以运行时类路径为准。
基本信息
| 适用平台 | Java Web 应用(Tomcat、WebLogic、WildFly 等) |
|---|---|
| 关键组件 | struts2-core、struts2-convention-plugin、ognl |
| 排查对象 | war/jar 内的 lib 目录、应用 lib 目录、容器共享库 |
| 基线 | Struts2 版本不在受影响范围且已打对应公告的补丁 |
| 风险等级 | 高 |
典型使用场景
- 资产清点:盘点哪些应用引入了 Struts2 及其版本
- 漏洞应急:新 S2 公告发布后立即比对受影响版本
- 上线前检查:新交付的 war 包核对依赖清单
- 遗留系统治理:老系统长期未升级,属于重点风险点
- 应急排查:怀疑被利用时查看是否存在异常请求与落地文件
排查命令
排查命令
find / -name 'struts2-core-*.jar' -o -name 'struts-*.jar' 2>/dev/null | head -20
unzip -l /path/to/app.war 2>/dev/null | grep -i struts | head
jar tf /path/to/app.war 2>/dev/null | grep -iE 'struts|ognl' | head
unzip -p /path/to/struts2-core-x.y.z.jar META-INF/MANIFEST.MF 2>/dev/null | head
# 运行中的应用可看类路径实际加载来源:
jcmd <pid> VM.class_hierarchy 2>/dev/null | head -5
ls -l /path/to/tomcat/webapps/*/WEB-INF/lib/ | grep -i struts排查结果判读
| 发现 | 含义 | 处置 |
|---|---|---|
| war 内 lib 有 struts2-core | 应用自带框架 | 核对版本是否受影响 |
| 外层 lib 与 war 内版本不同 | 存在多版本共存 | 以运行时实际加载为准,清理冗余 |
| 容器共享库含 struts | 多应用共用 | 升级需评估全部使用方 |
| 仅剩 ognl.jar | 框架已移除但依赖残留 | 确认无引用后清理 |
| 版本号无法识别 | 可能被改名打包 | 从 class 反查或咨询开发方 |
S2 系列漏洞通常伴随公开验证代码:公网可达的 Java 应用一旦发现旧版 Struts2,应按紧急漏洞处理,不能等常规窗口。
落地要点
- 依赖清单纳入发布产物:每次构建导出依赖树并存档
- 升级前在测试环境充分回归:自定义插件与拦截器可能与新版本不兼容
- war 包内版本与 lib 目录版本不一致时,以类路径实际加载为准
- 对无法升级的老系统,优先考虑下线、加访问控制或前置 WAF 缓解
- 把组件级清单写进资产台账,漏洞公告出来能立刻定位影响面
同名不同版本的 jar 共存是常见现象:只替换一个文件往往修不干净,需确认实际生效的那一份。