截至目前,您可能已经了解到Jakarta EE 9项目,该项目旨在为EE创新提供新的基础。

Jakarta EE 9是在EE 8之上的迭代发布,主要目的是将所有javax.包重命名为jakarta.包。

在一段时间内,我们将为EE 8和EE 9提供等效的Hibernate Validator版本:Hibernate Validator 6.x将保持javax.包,而Hibernate Validator 7.x将迁移到jakarta.包。

考虑到许多库依赖于javax.*包,Java生态系统的完全过渡可能需要数月甚至数年,因此我们将并行维护这两个版本,这也是为什么我们今天发布两个新版本的原因。

总结如下

  • 如果您正在使用javax.*包,本公告中的6.2部分适用于您

  • 如果您正在迁移到Jakarta EE 9和jakarta.*包,则应使用7.0版本。

关于使用javax.*包或jakarta.*包的一致性很重要,因此只有当您可以将整个堆栈迁移到Jakarta EE 9时,才升级到Hibernate Validator 7。

如果您不能这样做,您应继续使用Hibernate Validator 6.x。

如果您使用Dependabot并且想保持在6.x版本,请在Hibernate Validator 7升级拉取请求中发表评论,包含@dependabot ignore this major version

7个具体变更

Hibernate Validator 7是Jakarta Bean Validation 3的参考实现,它是Jakarta EE 9的一部分。

这意味着它使用jakarta.validation包。

此外,XML配置文件的命名空间已更改

再次强调,只有当您想要将整个堆栈迁移到Jakarta EE 9时,才升级到7版本。

7和6.2版本的新功能

表达式语言

在Hibernate Validator中,为了使所有内置约束消息正确插值,您需要在类路径中提供表达式语言实现,因为一些默认消息使用了表达式语言功能。

这些消息是您代码的一部分,因此表达式语言对这些消息进行插值不是问题。

问题是,当通过ConstraintValidatorContext创建带有消息模板的自定义违规时,这些消息也会由表达式语言引擎进行插值。

在大多数情况下,这是安全的。但如果你在消息模板中包含用户输入,你需要非常小心,因为你需要使用addExpressionVariable()来转义用户输入。

我们已经在以下地方讨论了与此相关的CVE:https://blog.hibernate.com.cn/2020/05/07/hibernate-validator-615-6020-released/ 。当时,我们决定这是一个正常的行为,与SQL注入非常相似:您需要以与编写SQL时相同的方式转义您的参数。我们还使现有文档更清晰,并将警告更加突出。

我们最近收到了一个新的报告,指出一个常用的库没有注意到这一点。这引发了我们之前遗漏的另一个问题:没有符合规范的安全方式。唯一的安全方式是使用Hibernate Validator特定的API。这意味着它不是实现无关的,如果您计划同时支持Hibernate Validator和Apache BVal,可能会出现问题。

这使得我们重新考虑了这种情况,我们决定深刻改变Hibernate Validator中处理表达式语言的方式,主要变化包括

  • 默认情况下,表达式语言对自定义违规是禁用的,即您从ConstraintValidatorContext创建的那些。

  • 您可以根据每个案例单独启用它,这意味着您可以在保持安全的情况下为特定的自定义违规启用EL。

  • 对于约束消息,默认情况下不再允许在您的表达式中调用bean方法。您可以访问bean属性,但不能调用bean方法。

  • 您可以分别针对约束和自定义违规对要启用的EL功能进行微调。

我们引入了表达式语言功能级别的概念,它定义了Expression Language引擎启用了哪些功能。

我们目前接受四个特征级别的值

  • NONE:完全禁用表达式语言插值。

  • VARIABLES:允许通过addExpressionVariable()注入的变量、资源包的使用以及formatter对象的插值。

  • BEAN_PROPERTIES:允许VARIABLES允许的一切,以及bean属性的插值。

  • BEAN_METHODS:还允许执行bean方法。对于硬编码的约束消息可以认为是安全的,但对于需要额外注意的自定义违规则不是。

BEAN_PROPERTIES是约束的默认值。

NONE是自定义违规的默认值。如果本地启用但没有指定功能级别,它将使用VARIABLES功能级别。

以下示例显示了如何为自定义违规启用表达式语言

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" )
                    .enableExpressionLanguage() (1)
                    .addConstraintViolation();

            return false;
        }

        return true;
    }

    private boolean isInvalid(String value) {
        // ...
        return false;
    }
}
1 为自定义违规启用表达式语言支持,使用默认的功能级别VARIABLES

请注意,如果需要,您可以定义更宽松的功能级别。但请非常小心,如果将用户输入包含到您的消息模板中,请使用addExpressionVariable()

您可以在文档中了解更多关于所有这些信息

虽然绝对不建议,但您可以通过使用本段末尾描述的两个属性,在不更改代码的情况下回到之前的行为。请参阅我们的文档中的这两个属性

@SafeHtml 移除

@SafeHtml 约束计划移除一段时间了。

它已经被从 6.2 和 7 版本中删除,没有替代方案。[链接]

新的 @INN 约束

新增了一个针对俄罗斯的特定约束 - @INN - 允许验证俄罗斯纳税人的识别号。

内置 ValueExtractors 不使用反射设置

我们收到报告称,我们用来设置 ValueExtractor(用于支持容器元素约束,例如 List<@NotNull String>)的反射 API 的方法不支持 Android Java 版本。

为了减轻这种情况,内置的 ValueExtractor 现在不再使用反射进行设置。

自定义 ValueExtractor 的设置仍然需要反射,因此它们很可能在 Android 上无法工作。

获取 6.2.0.Final 版本

要使用 Maven、Gradle 等获取发布版本,请使用 GAV 坐标 org.hibernate.validator:{hibernate-validator|hibernate-validator-cdi|hibernate-validator-annotation-processor}:6.2.0.Final。请注意,group id 从 org.hibernate(Hibernate Validator 5 及更早版本)更改为 org.hibernate.validator(从 Hibernate Validator 6 开始)。

或者,可以在 SourceForge 上找到包含所有内容的分发包(TAR.GZZIP)。

获取 7.0.0.Final 版本

要使用 Maven、Gradle 等获取发布版本,请使用 GAV 坐标 org.hibernate.validator:{hibernate-validator|hibernate-validator-cdi|hibernate-validator-annotation-processor}:7.0.0.Final。请注意,group id 从 org.hibernate(Hibernate Validator 5 及更早版本)更改为 org.hibernate.validator(从 Hibernate Validator 6 开始)。

或者,可以在 SourceForge 上找到包含所有内容的分发包(TAR.GZZIP)。

反馈、问题、想法?

要联系,请使用常规渠道

接下来是什么?

根据我们从这两个候选版本收到的反馈,我们将在未来几周内发布这两个最终版本。


返回顶部