Struts 2 漏洞(上)

一、简述

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/passwdWEB-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限制允许的参数名,禁止危险参数(如methodredirect);
  • 对文件上传做 "三重校验":文件名 + 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>

总结

  1. Struts 2 的核心风险是OGNL 表达式注入导致的 RCE,几乎所有高危漏洞都源于此,升级到最新稳定版是最核心的防护手段;
  2. 加固的关键是禁用动态方法调用、限制 OGNL 权限、严格校验用户输入,尤其是文件上传和请求头 / 参数;
  3. 部署层面需配合 WAF 拦截恶意请求,同时以最小权限运行应用,降低漏洞被利用后的危害。
相关推荐
galaxyffang2 小时前
Java堆内存诊断:从工具使用到实战分析
java·jvm
梵得儿SHI2 小时前
Spring Cloud 实战攻坚:企业级用户服务开发(注册登录 + JWT 认证 + 权限控制)
后端·spring·spring cloud·用户注册与登录·jwt无状态认证体系·rbac权限控制·微服务用户中心
HAPPY酷3 小时前
C++ 成员指针(Pointer to Member)完全指南
java·c++·算法
Sunsets_Red3 小时前
浅谈随机化与模拟退火
java·c语言·c++·python·算法·c#·信息学竞赛
星火开发设计3 小时前
模板参数:类型参数与非类型参数的区别
java·开发语言·前端·数据库·c++·算法
星辰徐哥3 小时前
Java数组的定义、操作与应用场景
java·开发语言
Aileen_0v03 小时前
【数据结构中链表常用的方法实现过程】
java·开发语言·数据结构·算法·链表·动态规划·csdn开发云
Andy Dennis4 小时前
一文认识Java常见集合
java·开发语言
玹外之音5 小时前
Spring AI 实战:手把手教你构建支持多会话管理的智能聊天服务
java·spring