# DeepAudit 安全审计报告

---

## 报告信息

| 属性 | 内容 |
|----------|-------|
| **项目名称** | struts-2-5-16 |
| **任务 ID** | `5740cd77...` |
| **生成时间** | 2026-07-07 12:10:47 |
| **任务状态** | COMPLETED |
| **耗时** | 10.9 分钟 |

## 执行摘要

**安全评分: 0/100** [未通过]
*严重 - 需要立即进行修复*

### 漏洞发现概览

| 严重程度 | 数量 | 已验证 |
|----------|-------|----------|
| **高危 (HIGH)** | 8 | 0 |
| **中危 (MEDIUM)** | 8 | 0 |
| **总计** | 16 | 0 |

### 审计指标

- **分析文件数:** 3182 / 3182
- **Agent 迭代次数:** 74
- **工具调用次数:** 73
- **Token 消耗:** 1,633,462

## 高危 (High) 漏洞

### HIGH-1: core/src/main/java/org/apache/struts2/dispatcher/mapper/ - Action 映射模块，URL 路由处理可能存在问题

**[未验证]** | 类型: `other`

**AI 置信度:** 60%

**漏洞描述:**

core/src/main/java/org/apache/struts2/dispatcher/mapper/ - Action 映射模块，URL 路由处理可能存在问题

---

### HIGH-2: DebuggingInterceptor Browser 模式 OGNL 注入

**[未验证]** | 类型: `command_injection`

**AI 置信度:** 50%

**漏洞描述:**

DebuggingInterceptor 的 BROWSER_MODE 模式下，从请求参数 'object' 获取 OGNL 表达式并通过 stack.findValue(rootObjectExpression) 执行。默认值为 '#context'，但攻击者可以控制该参数执行任意 OGNL 表达式。这提供了另一个 OGNL 注入的攻击面。

**漏洞代码:**

```text
} else if (BROWSER_MODE.equals(type)) {
    actionOnly = true;
    inv.addPreResultListener(new PreResultListener() {
        public void beforeResult(ActionInvocation inv, String actionResult) {
            String rootObjectExpression = getParameter(OBJECT_PARAM);
            if (rootObjectExpression == null)
                rootObjectExpression = "#context";
            ...
            Object rootObject = stack.findValue(rootObjectExpression);
```

**修复建议:**

1. 移除 DebuggingInterceptor 或仅在严格受控的环境中使用
2. 对 object 参数进行严格的输入验证
3. 限制可访问的 OGNL 上下文对象

---

### HIGH-3: core/src/main/java/org/apache/struts2/dispatcher/multipart/ - 文件上传处理模块，历史上存在多个高危 RCE 漏洞（S2-045, S2-0

**[未验证]** | 类型: `other`

**AI 置信度:** 60%

**漏洞描述:**

core/src/main/java/org/apache/struts2/dispatcher/multipart/ - 文件上传处理模块，历史上存在多个高危 RCE 漏洞（S2-045, S2-046）

---

### HIGH-4: core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java - 核心调度器，处理所有请求分发，OGNL 表达式执行入口

**[未验证]** | 类型: `other`

**AI 置信度:** 60%

**漏洞描述:**

core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java - 核心调度器，处理所有请求分发，OGNL 表达式执行入口

---

### HIGH-5: core/src/main/java/org/apache/struts2/interceptor/ - 拦截器模块，参数绑定和验证逻辑可能存在 OGNL 注入风险

**[未验证]** | 类型: `other`

**AI 置信度:** 60%

**漏洞描述:**

core/src/main/java/org/apache/struts2/interceptor/ - 拦截器模块，参数绑定和验证逻辑可能存在 OGNL 注入风险

---

### HIGH-6: core/src/main/java/org/apache/struts2/views/ - 视图渲染模块，可能存在模板注入风险

**[未验证]** | 类型: `other`

**AI 置信度:** 60%

**漏洞描述:**

core/src/main/java/org/apache/struts2/views/ - 视图渲染模块，可能存在模板注入风险

---

### HIGH-7: core/src/main/java/org/apache/struts2/components/ - UI 组件模块，标签处理可能引入 XSS 漏洞

**[未验证]** | 类型: `xss`

**AI 置信度:** 60%

**漏洞描述:**

core/src/main/java/org/apache/struts2/components/ - UI 组件模块，标签处理可能引入 XSS 漏洞

---

### HIGH-8: StrutsRequestWrapper OGNL 表达式求值漏洞

**[未验证]** | 类型: `command_injection`

**AI 置信度:** 50%

**漏洞描述:**

StrutsRequestWrapper.getAttribute() 方法在请求属性未找到时，会通过 stack.findValue(key) 将属性名作为 OGNL 表达式求值。这意味着如果攻击者能够控制请求属性名（例如通过某些框架特性或请求头），就可以注入恶意的 OGNL 表达式。虽然代码中排除了包含 '#' 字符的属性名，但仍有其他绕过可能。

**漏洞代码:**

```text
public Object getAttribute(String key) {
    ...
    if (ctx != null && attribute == null) {
        boolean alreadyIn = isTrue((Boolean) ctx.get(REQUEST_WRAPPER_GET_ATTRIBUTE));
        if (!alreadyIn && !key.contains("#")) {
            ...
            attribute = stack.findValue(key);
        }
    }
    return attribute;
}
```

**修复建议:**

1. 移除或禁用 ValueStack 查找逻辑
2. 对请求属性名进行更严格的过滤，不仅排除 '#' 字符
3. 考虑使用白名单机制，只允许特定的属性名通过
4. 升级到最新版本的 Struts 2 框架

---

## 中危 (Medium) 漏洞

### MEDIUM-1: OGNL 排除模式可能被绕过

**[未验证]** | 类型: `other`

**AI 置信度:** 50%

**漏洞描述:**

DefaultExcludedPatternsChecker 中定义的排除模式用于阻止对敏感 OGNL 对象的访问（如 session、request、response、_memberAccess 等）。然而，排除模式 '(^|\\%\\{)((#?)(top(\\.|\\['|\\[")|\\[\\d\\]\\.)?)(dojo|struts|session|request|response|application|servlet(Request|Response|Context)|parameters|context|_memberAccess)(\\.|\\[).*' 可能存在绕过方式，例如通过 Unicode 编码、大小写变换或其他 OGNL 特性。

**漏洞代码:**

```text
public static final String[] EXCLUDED_PATTERNS = {
    "(^|\\%\\{)((#?)(top(\\.|\\['|\\[")|\\[\\d\\]\\.)?)(dojo|struts|session|request|response|application|servlet(Request|Response|Context)|parameters|context|_memberAccess)(\\.|\\[).*",
    ".*(^|\\.|\\[|\\'|\"|get)class(\\(\\.|\\[|\\'|\").*"
};
```

**修复建议:**

1. 定期审查和更新排除模式以应对新的绕过技术
2. 考虑使用多层防御策略，不仅依赖排除模式
3. 升级到最新的 Struts 2 版本
4. 监控安全公告中关于排除模式绕过的 CVE

---

### MEDIUM-2: 文件上传路径处理潜在风险

**[未验证]** | 类型: `path_traversal`

**AI 置信度:** 50%

**漏洞描述:**

AbstractMultiPartRequest.getCanonicalName() 方法处理上传文件名时，虽然尝试提取文件名（去除路径分隔符），但 JakartaMultiPartRequest 的 getFile() 方法直接使用 DiskFileItem 的 storeLocation 创建 StrutsUploadedFile 对象。如果 saveDir 配置不当或文件名处理存在缺陷，可能导致路径遍历攻击。此外，getFileNames() 方法返回经过 getCanonicalName() 处理的文件名，但 getFilesystemName() 直接返回存储位置的文件名，两者可能不一致。

**漏洞代码:**

```text
protected String getCanonicalName(final String originalFileName) {
    String fileName = originalFileName;
    int forwardSlash = fileName.lastIndexOf('/');
    int backwardSlash = fileName.lastIndexOf('\\');
    if (forwardSlash != -1 && forwardSlash > backwardSlash) {
        fileName = fileName.substring(forwardSlash + 1, fileName.length());
    } else {
        fileName = fileName.substring(backwardSlash + 1, fileName.length());
    }
    return fileName;
}
```

**修复建议:**

1. 对上传文件名进行更严格的验证，包括检查是否包含 '..' 路径遍历序列
2. 确保 saveDir 配置为安全的隔离目录
3. 考虑对文件名进行随机化处理，避免使用用户提供的文件名
4. 实施文件类型白名单验证

---

### MEDIUM-3: Struts 2.5.16 已知历史漏洞风险

**[未验证]** | 类型: `other`

**AI 置信度:** 50%

**漏洞描述:**

项目使用 Apache Struts 2.5.16 版本，该版本虽然修复了部分已知漏洞，但仍需关注 S2-045（文件上传 RCE）、S2-046（文件上传 RCE）、S2-048（Struts 1 插件 RCE）、S2-052（XStream RCE）、S2-057（命名空间 RCE）等历史漏洞的变种。

---

### MEDIUM-4: OGNL 表达式引擎版本

**[未验证]** | 类型: `other`

**AI 置信度:** 50%

**漏洞描述:**

使用 OGNL 3.1.15 版本，OGNL 表达式注入是 Struts 2 框架最核心的安全风险，需要重点审计 OGNL 表达式执行路径。

---

### MEDIUM-5: Log4j 2.10.0 已知漏洞 (Log4Shell)

**[未验证]** | 类型: `other`

**AI 置信度:** 50%

**漏洞描述:**

项目使用 Log4j 2.10.0 版本，该版本存在严重的 Log4Shell 漏洞（CVE-2021-44228）。攻击者可以通过 JNDI 注入实现远程代码执行。虽然这是依赖版本问题而非代码逻辑漏洞，但影响严重，需要立即处理。

**漏洞代码:**

```text
<!-- Log4j 2.10.0 -->
```

**修复建议:**

1. 立即升级 Log4j 到 2.17.1 或更高版本
2. 如果无法升级，设置系统属性 log4j2.formatMsgNoLookups=true
3. 移除 JndiLookup 类

---

### MEDIUM-6: Jackson 2.9.4 反序列化漏洞风险

**[未验证]** | 类型: `deserialization`

**AI 置信度:** 50%

**漏洞描述:**

项目使用 Jackson 2.9.4 版本，该版本存在多个已知的反序列化漏洞（如 CVE-2017-17485, CVE-2018-5968 等）。如果项目中使用 Jackson 处理 JSON 数据，攻击者可能通过构造恶意的 JSON 数据实现远程代码执行。

**漏洞代码:**

```text
<!-- Jackson 2.9.4 -->
```

**修复建议:**

1. 升级 Jackson 到 2.9.10 或更高版本
2. 启用 Jackson 的默认类型安全验证
3. 避免使用 enableDefaultTyping()

---

### MEDIUM-7: Spring Platform 4.3.13.RELEASE

**[未验证]** | 类型: `other`

**AI 置信度:** 50%

**漏洞描述:**

使用 Spring Platform 4.3.13.RELEASE，该版本存在已知漏洞，需要关注 Spring 集成部分的安全风险。

---

### MEDIUM-8: Multipart Content-Type 验证绕过风险

**[未验证]** | 类型: `other`

**AI 置信度:** 50%

**漏洞描述:**

Dispatcher.java 中的 multipartValidationPattern 正则表达式对 multipart 请求的 Content-Type 验证存在潜在绕过风险。正则表达式为 '^multipart/form-data(; boundary=[0-9a-zA-Z'()+_,\-./:=?]{1,70})?(;charset=[a-zA-Z\-0-9]{3,14})?'，其中 charset 参数验证较弱，且 boundary 参数长度限制为 70 字符。历史上 Struts 2 的 multipart 处理模块存在多个 RCE 漏洞（S2-045, S2-046），这些漏洞正是通过 Content-Type 头注入 OGNL 表达式实现的。

**漏洞代码:**

```text
public static final String MULTIPART_FORM_DATA_REGEX = "^multipart/form-data(; boundary=[0-9a-zA-Z'()+_,\\-./:=?]{1,70})?(;charset=[a-zA-Z\\-0-9]{3,14})?";
```

**修复建议:**

1. 升级到最新的 Struts 2 版本以获取完整的安全补丁
2. 审查 multipart 请求处理逻辑，确保 Content-Type 头中的 OGNL 表达式不会被意外执行
3. 考虑使用更严格的 Content-Type 验证
4. 在 Web 服务器层面（如 Apache/Nginx）添加额外的请求过滤规则

---

## 修复优先级建议

基于已发现的漏洞，我们建议按以下优先级进行修复：

1. **高优先级:** 在 1 周内修复 8 个高危漏洞
2. **中优先级:** 在 2-4 周内修复 8 个中危漏洞

---

*本报告由 DeepAudit - AI 驱动的安全分析系统生成*
