前言:
最新扫描jar包发现spring-security-crypto新出了个漏洞CVE-2025-22228,详细信息如下:
https://spring.io/security/cve-2025-22228
漏洞分析:
看了下具体漏洞位于密码比对的地方位于org.springframework.security.crypto.bcrypt下的String hashpw(byte[] passwordb, String salt, boolean for_check)方法
看了下只要是超过72位后加密的密码都相同,测试了下,代码如下
package org.example;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class Main {
public static void main(String[] args) {
// 原始密码
String password1 = "123456789012345678901234567890123456789012345678901234567890123456789012";
String password2 = "123456789012345678901234567890123456789012345678901234567890123456789012aaaaaaa";
// 生成盐值
String salt = BCrypt.gensalt();
// 使用推荐的方法进行哈希处理
String hashedPassword1 = BCrypt.hashpw(password1, salt);
String hashedPassword2 = BCrypt.hashpw(password2, salt);
// 输出哈希后的密码
System.out.println("Hashed Password: " + hashedPassword1);
System.out.println("Hashed Password: " + hashedPassword2);
}
}
可以看到只要加密的密码长度大于72个字符,后面的字符无论是什么加密产生的结果都相同
这个就很鸡肋了,有谁设置密码会大于等于72个字符,所以基本没啥用;
漏洞修复:
5.8.16及以下版本不再提供修复版本,除非付费的企业用户
因此需要修改源代码来修复该问题,首先安装环境需要jdk11及以上版本,另外需要安装 apache-groovy-sdk
https://groovy.jfrog.io/ui/native/dist-release-local/groovy-zips/apache-groovy-sdk-3.0.10.zip
安装成功后,需要修复如下代码
org.springframework.security.crypto.bcrypt的private static String hashpw(byte passwordb[], String salt, boolean for_check) 方法中添加
if (passwordb.length > 72) {
throw new IllegalArgumentException("password cannot be more than 72 bytes");
}
另外org.springframework.security.crypto.bcrypt下添加检测方法enforcePasswordLength
@Test
public void enforcePasswordLength() {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String password72chars = "123456789012345678901234567890123456789012345678901234567890123456789012";
assertThat(encoder.matches(password72chars, encoder.encode(password72chars))).isTrue();
String password73chars = password72chars.concat("a");
assertThatIllegalArgumentException()
.isThrownBy(() -> encoder.matches(password73chars, encoder.encode(password73chars)));
}
完成后另外需要修改
gradlew.bat :spring-security-crypto:checkFormatMain
当出现如上错误证明代码格式存在问题,需要关闭 build.gradle中的sonar检测,由于会默认进行安全检查,如果系统没有安装相关插件建议关闭,注释如下位置
另外gradle.properties中添加
sonar.skip=true
完成后检查格式是否正确
gradlew.bat format
格式修复完成后编译成功:
gradlew.bat :spring-security-crypto:build
后记:
漏洞原理非常简单,就是加密的长度不能超过72个字符,超过的地方就不会进行加密,这样就可能导致在验证密码的地方进行绕过,但是没见过密码设置超过72个字符的人,所以这个漏洞现实意义不大;