为协助缓解 CVE-2022-xxxx 的修复步骤,您可以使用此工具检查数据库中需要更新的哈希。
在您将应用程序 与数据库集成 后,该工具分两步工作。
为了演示,这里使用了一个内存中的示例应用程序。
在该示例应用程序上,您可以像这样运行 check 步骤:
./mvnw spring-boot:run@check
这将检查示例数据库中任何需要更新的 BCrypt 哈希。
然后,您可以像这样运行 update 步骤:
./mvnw spring-boot:run@update
这将尝试更新在示例数据库中检测到的任何易受攻击的哈希。
示例应用程序使用提供的 VulnerabilityCheck 类来检查和更新每个密码哈希。
警告:仅在将应用程序更新为使用低于 31 的轮数后再执行这些步骤。 OWASP 目前建议值为 10,但在某些高性能系统上,也可能使用高达 16 的值。
该工具附带一个用于测试的内存示例。 您需要用您自己的类替换它,以便与您的数据集成。
为此,首先克隆此仓库。
然后,将 sample 包中的代码替换为能够访问您应用程序中密码数据的代码。
您可能需要编写代码来检查现有密码是否易受攻击。
您还需要编写代码来更新任何受影响的哈希。
在这两种情况下,您都可以使用 VulnerabilityCheck 来检查和更新给定的哈希。
提示:在编写上述代码时,请考虑您需要更新的密码数量。 请记住,数据库连接可能失败,计算机可能崩溃,内存可能耗尽等等。 例如,不建议一次性将数百万条记录加载到内存中。
更新密码哈希后,您现在可以更新到最新的 Spring Security。 如果您正在使用 Spring Security 的密码更新功能,那么当用户登录时,他们的密码将自动使用您新配置的轮数值重新哈希。
问:如何知道我的哈希是否易受攻击?
答:如果哈希是使用 Spring Security 的 BCrypt 类(工作因子为 31)进行哈希的,则它们容易受到攻击。
您可以通过检查系统中由 Spring Security 管理的密码哈希来确认。
如果它们以 '{bcrypt}$2a$31'、'{bcrypt}$2b$31'、'{bcrypt}$2y$31'、'{bcrypt}$2$31'、'$2a$31'、'$2b$31'、'$2y$31' 或 '$2$31' 开头,那么该密码是易受攻击的,需要更新。
问:我应该如何更改我的应用程序?
答:OWASP 推荐 BCrypt 的工作因子为 10。 一些高性能系统会使用高达 16 的值。 每个系统都不同,BCrypt 设计为能够根据需要随着时间的推移增加工作因子。
问:我应该在哪里更改我的应用程序?
答:您可能通过像这样构造 BCryptPasswordEncoder 来设置工作因子:
new BCryptPasswordEncoder(31)
它可能出现在像这样的 Bean 定义中:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(31);
}
您可以搜索该字符串并更新它。 请注意,工作因子可能由外部属性驱动,这意味着您应该改在外部配置中修改它。
问:我刚更新了 Spring Security,现在部分或全部登录和用户注册都挂起了。发生了什么?
答:从 Spring Security 5.5.7+、5.6.4+、5.7.0+ 开始,指示工作因子为 31 的密码哈希—— 例如,以 '{bcrypt}$2a$31'、'{bcrypt}$2b$31'、'{bcrypt}$2y$31'、'{bcrypt}$2$31'、'$2a$31'、'$2b$31'、'$2y$31' 或 '$2$31' 开头——每次哈希计算将需要 2-3 天。 为了缓解这种情况,您需要将 Spring Security 更改为使用较低的轮数。 然后,使用此工具更新易受攻击的密码哈希。
问:我完成了所有三个建议的步骤(更改 BCryptPasswordEncoder 配置、更新密码哈希和更新 Spring Security)。 但修改后的密码哈希并没有更新到我新配置的工作因子。我该怎么办?
确保您已发布一个 UserDetailsPasswordService 类型的 Bean。
这个 Bean 用于将密码更新到新的 BCrypt 对数轮数。
问:为什么 Spring Security 不能在升级时直接更新易受攻击的密码,而不需要这个工具?
首先,因为在最新的 Spring Security 中,工作因子为 31 的密码哈希会被正确计算,因此每次需要 2-3 天。 假设这对应用程序来说是合理的成本,是不切实际的期望。
其次,Spring Security 仅支持增加工作因子(例如从 10 到 12),而不支持减少(例如从 31 到 10)。