我们刚刚发布了 Hibernate Validator 6.1.5.Final,其中包含了对 CVE-2020-10693 的修复和一些其他的小修复。
这是一个推荐升级版本,适用于所有使用 Hibernate Validator 的用户,并且可以直接替换 6.1.4.Final。
我们还发布了 6.0.20.Final,其中也包括了对 CVE-2020-10693 的修复。
新特性
CVE-2020-10693
首先介绍一下背景:为了在约束违反信息生成方面提供一定的灵活性,Hibernate Validator 默认启用了一个表达式语言(基于 Jakarta EL)。
这意味着在创建约束违反信息时,字符串在返回给用户之前会被传递到表达式语言中。表达式语言非常灵活,允许执行任意 Java 代码。我们在 Hibernate Validator 中通过调整 EL 配置来限制了一些功能,但毫无疑问,你可以找到一些复杂的方法来执行代码。
当使用内置约束时,这绝对不是问题。当使用自定义约束时,只要你不将用户输入包含在约束违反信息中,这也不是问题……只要你不包含用户输入。通过包含用户输入,你最终会将任意字符串传递给 EL,而这些任意字符串可能包含精心制作的内容,要么泄露敏感数据(例如,在 User
实体中存在的密码散列),要么执行代码。
现在你读到这里,你可能认为这是一个严重的安全问题,你完全正确。这就是为什么我们一直建议不要将用户输入原样包含在约束违反信息中,而是使用表达式变量,这样可以防止 EL 注入。这与 SQL 注入的问题完全相同:最好使用你的驱动程序提供的参数处理功能,而不是拼接字符串。
CVE-2020-10693 是关于应用程序容易受到 EL 注入的影响,如果它们没有仔细转义用户输入(即,仅将 ${
转义为 \${
而不是应该的 \$\{
),这是由于我们解析器中的一个错误。其严重性为中等,因为,如上所述,你不应该自己处理转义,而应该真正依赖表达式变量。如果你这样做,你不会受到此 CVE 的影响。
简而言之,在实现自己的ConstraintValidator
时,你绝对不应该做的事情
public class UnsafeValidator implements ConstraintValidator<ZipCode, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if ( value == null ) {
return true;
}
context.disableDefaultConstraintViolation();
if ( isInvalid( value ) ) {
context
.buildConstraintViolationWithTemplate( value + " is not a valid ZIP code" )
.addConstraintViolation();
return false;
}
return true;
}
private boolean isInvalid(String value) {
// ...
return false;
}
}
而你应该采取的做法
public class SafeValidator implements ConstraintValidator<ZipCode, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if ( value == null ) {
return true;
}
HibernateConstraintValidatorContext hibernateContext = context.unwrap(
HibernateConstraintValidatorContext.class );
hibernateContext.disableDefaultConstraintViolation();
if ( isInvalid( value ) ) {
hibernateContext
.addExpressionVariable( "validatedValue", value )
.buildConstraintViolationWithTemplate( "${validatedValue} is not a valid ZIP code" )
.addConstraintViolation();
return false;
}
return true;
}
private boolean isInvalid(String value) {
// ...
return false;
}
}
你可以在我们的参考文档中了解更多信息。
感谢GitHub安全团队,特别是Alvaro Munoz就这个问题与我们联系,并且联系受影响的项目,以便它们能够根据我们的建议调整它们的代码。
完整的变更日志
已修复问题的完整列表可以在我们的JIRA上找到此处。
获取6.1.5.Final
要使用Maven、Gradle等获取发布版本,请使用以下GAV坐标
-
org.hibernate.validator:hibernate-validator:6.1.5.Final
-
org.hibernate.validator:hibernate-validator-cdi:6.1.5.Final
-
org.hibernate.validator:hibernate-validator-annotation-processor:6.1.5.Final
请注意,组ID已从org.hibernate
(Hibernate Validator 5及之前版本)更改为org.hibernate.validator
(自Hibernate Validator 6开始)。
如果你想在WildFly上利用此版本的全新功能,我们还提供了WildFly补丁,适用于WildFly 19和WildFly 18.0.1。你可以在此处了解如何应用此类补丁。
反馈、问题、想法?
要取得联系,请使用常规渠道
-
用户论坛(使用问题,一般反馈)
-
问题跟踪器(错误报告,功能请求)
-
邮件列表(与开发相关的讨论)
-
Bean Validation开发邮件列表(关于Bean Validation规范讨论)