一、简述
Struts 2 是 Java 经典的 MVC 框架,因OGNL 表达式注入、远程代码执行(RCE)、文件上传 / 下载漏洞频发而成为网络安全的重点关注对象。
二、Struts 2 核心高危漏洞(RCE 为主)
1. OGNL 表达式注入(最核心、最频发)
Struts 2 的核心风险源于OGNL(Object-Graph Navigation Language) 表达式解析机制 ------ 用户输入若未被过滤直接带入 OGNL 解析,会导致任意代码执行。
典型高危 CVE:
| CVE 编号 | 漏洞名称 | 威胁等级 | 影响版本 | 核心原理 |
|---|---|---|---|---|
| CVE-2017-5638 | Struts2-045 | 严重 | 2.3.5-2.3.31、2.5-2.5.10 | Content-Type 头注入 OGNL 表达式,触发 RCE |
| CVE-2017-9791 | Struts2-048 | 严重 | 2.3.x、2.5.x | 上传文件时,文件名 / Content-Disposition 头注入 OGNL 表达式 |
| CVE-2018-11776 | Struts2-057 | 严重 | 2.3.x、2.5.x | 通配符 Action 配置 + 默认静态方法调用,绕过 OGNL 过滤执行代码 |
| CVE-2023-50164 | Struts2-066 | 高 | 2.5.0-2.5.32、6.1.0-6.3.0 | 动态方法调用(DMI)未过滤,通过method:前缀注入 OGNL 表达式 |
漏洞利用示例(原理级,仅用于理解):
恶意请求头(Struts2-045):
bash
Content-Type: %{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('cmd','whoami')}.multipart/form-data
最终会在服务器执行whoami命令,获取当前进程用户。
修复方案:
-
核心:升级版本 (最有效):
- 2.3.x 升级至 2.3.34+
- 2.5.x 升级至 2.5.12+
- 6.x 升级至 6.3.0.2+
-
临时防护 (未升级前):在
struts.xml中禁用动态方法调用、限制 OGNL 解析:XML<struts> <!-- 禁用动态方法调用 --> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <!-- 限制OGNL允许的类/方法 --> <constant name="struts.ognl.allowStaticMethodAccess" value="false" /> <!-- 过滤危险请求头/参数 --> <constant name="struts.multipart.parser" value="jakarta" /> </struts>
2. 文件上传漏洞
漏洞原理:
Struts 2 默认的文件上传解析器未严格校验文件类型、文件名,攻击者可上传jsp/class等恶意文件,结合路径遍历执行代码。
典型场景:
- 上传文件名包含
../,绕过目录限制(如上传到WEB-INF/classes); - 伪造文件 MIME 类型(如将
shell.jsp伪装为image/png); - 利用 Struts 2 的
FileUploadInterceptor过滤绕过。
修复方案:
XML
<!-- 在struts.xml中配置文件上传拦截器,严格限制 -->
<interceptor-ref name="fileUpload">
<!-- 允许的文件类型(白名单) -->
<param name="allowedTypes">image/jpeg,image/png,application/pdf</param>
<!-- 允许的文件大小(单位:字节) -->
<param name="maximumSize">1048576</param>
</interceptor-ref>
<!-- 自定义拦截器,校验文件名(禁止../、特殊字符) -->
3. 路径遍历 / 信息泄露
漏洞原理:
Struts 2 的静态资源访问、Action 路径解析未过滤../等路径遍历字符,导致读取服务器任意文件(如/etc/passwd、WEB-INF/web.xml)。
典型 CVE:CVE-2021-31805
- 影响版本:2.0.0-2.5.29
- 危害:通过构造
/struts2-showcase/${(new java.io.File('/etc/passwd')).text}读取敏感文件。
修复方案:
- 升级至最新版本;
- 配置 Struts 2 的
struts.action.extension,限制 Action 后缀(如仅允许.action); - 禁用静态资源的 OGNL 解析。
4. CSRF / 权限绕过
漏洞原理:
- Struts 2 默认未启用 CSRF 防护,攻击者可伪造请求执行敏感操作(如修改密码、提交订单);
- 部分版本的权限拦截器(
RolesInterceptor)可通过参数篡改绕过角色校验。
修复方案:
XML
<!-- 启用CSRF防护 -->
<constant name="struts.enable.CsrfProtection" value="true" />
<!-- 配置CSRF令牌验证 -->
<interceptor-ref name="csrf"/>
<!-- 严格配置角色权限,避免通配符 -->
<action name="admin/*" class="AdminAction">
<interceptor-ref name="roles">
<param name="allowedRoles">ADMIN</param>
</interceptor-ref>
</action>
三、Struts 2 安全加固最佳实践
1. 版本与依赖管理
- 强制升级:放弃 2.3.x/2.5.x 旧版本,优先使用 6.3.0.2+(最新稳定版);
- 依赖扫描 :使用 OWASP Dependency-Check 扫描项目依赖,移除
struts2-core之外的高危附属依赖(如旧版 ognl.jar); - 禁用废弃功能 :如静态方法调用、动态方法调用、OGNL 的
#context访问。
2. 输入校验与过滤
- 所有用户输入 (参数、请求头、文件名)必须经过白名单校验,禁止包含 OGNL 特殊字符(
%{、#、}); - 使用 Struts 2 的
ParametersInterceptor限制允许的参数名,禁止危险参数(如method、redirect); - 对文件上传做 "三重校验":文件名 + MIME 类型 + 文件内容(如校验图片的文件头)。
3. 部署层防护
- WAF 拦截 :在 Nginx / 云 WAF 中配置规则,拦截包含
%{、ognl:、method:的恶意请求; - 最小权限运行:运行 Struts 应用的 Tomcat/Jetty 进程使用非 root / 管理员权限,限制文件读写范围;
- 日志审计:开启 Struts 2 的详细日志,监控异常请求(如包含 OGNL 表达式的请求)。
4. 禁用危险配置
XML
<!-- struts.xml 安全配置模板 -->
<struts>
<!-- 基础安全常量 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.ognl.allowStaticMethodAccess" value="false" />
<constant name="struts.enable.CsrfProtection" value="true" />
<constant name="struts.multipart.maxSize" value="1048576" />
<constant name="struts.action.extension" value="action" />
<constant name="struts.ognl.excludedClasses" value="java.lang.Runtime,java.lang.ProcessBuilder" />
<!-- 全局拦截器 -->
<package name="basePackage" extends="struts-default" abstract="true">
<interceptors>
<interceptor-stack name="secureStack">
<interceptor-ref name="csrf"/>
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/jpeg,image/png</param>
</interceptor-ref>
<interceptor-ref name="params">
<param name="excludeParams">^method:.*,^ognl:.*</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="secureStack"/>
</package>
</struts>
总结
- Struts 2 的核心风险是OGNL 表达式注入导致的 RCE,几乎所有高危漏洞都源于此,升级到最新稳定版是最核心的防护手段;
- 加固的关键是禁用动态方法调用、限制 OGNL 权限、严格校验用户输入,尤其是文件上传和请求头 / 参数;
- 部署层面需配合 WAF 拦截恶意请求,同时以最小权限运行应用,降低漏洞被利用后的危害。