From 0886e89900d343ea20fde5137c9a3086e6da9ac9 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 19 Oct 2017 15:38:27 +0200 Subject: [PATCH] HV-1498 Fix privilege escalation when running under the security manager --- documentation/src/main/asciidoc/ch01.asciidoc | 2 ++ .../HibernateValidatorPermission.java | 29 +++++++++++++++++++ .../internal/engine/ValidatorImpl.java | 6 ++++ .../metadata/aggregated/PropertyMetaData.java | 6 ++++ .../privilegedactions/GetDeclaredField.java | 1 - tck-runner/src/test/resources/test.policy | 5 ++++ 6 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java diff --git a/documentation/src/main/asciidoc/ch01.asciidoc b/documentation/src/main/asciidoc/ch01.asciidoc index 6d90241344..ce9a244061 100644 --- a/documentation/src/main/asciidoc/ch01.asciidoc +++ b/documentation/src/main/asciidoc/ch01.asciidoc @@ -106,6 +106,8 @@ grant codeBase "file:path/to/hibernate-validator-{hvVersion}.jar" { permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.RuntimePermission "setContextClassLoader"; + permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; + // Only needed when working with XML descriptors (validation.xml or XML constraint mappings) permission java.util.PropertyPermission "mapAnyUriToUri", "read"; }; diff --git a/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java b/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java new file mode 100644 index 0000000000..71b33b75fb --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java @@ -0,0 +1,29 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator; + +import java.security.BasicPermission; + +/** + * Our specific implementation of {@link BasicPermission} as we cannot define additional {@link RuntimePermission}. + *

+ * {@code HibernateValidatorPermission} is thread-safe and immutable. + * + * @author Guillaume Smet + */ +public class HibernateValidatorPermission extends BasicPermission { + + public static final HibernateValidatorPermission ACCESS_PRIVATE_MEMBERS = new HibernateValidatorPermission( "accessPrivateMembers" ); + + public HibernateValidatorPermission(String name) { + super( name ); + } + + public HibernateValidatorPermission(String name, String actions) { + super( name, actions ); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 8b67f64beb..9ac7a1f8f0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -40,6 +40,7 @@ import javax.validation.groups.Default; import javax.validation.metadata.BeanDescriptor; +import org.hibernate.validator.HibernateValidatorPermission; import org.hibernate.validator.internal.engine.ValidationContext.ValidationContextBuilder; import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager; import org.hibernate.validator.internal.engine.groups.Group; @@ -1771,6 +1772,11 @@ private Member getAccessible(Member original) { return member; } + SecurityManager sm = System.getSecurityManager(); + if ( sm != null ) { + sm.checkPermission( HibernateValidatorPermission.ACCESS_PRIVATE_MEMBERS ); + } + Class clazz = original.getDeclaringClass(); if ( original instanceof Field ) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 911eb3f323..95ea78779e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -25,6 +25,7 @@ import javax.validation.ElementKind; import javax.validation.metadata.GroupConversionDescriptor; +import org.hibernate.validator.HibernateValidatorPermission; import org.hibernate.validator.internal.engine.valuehandling.UnwrapMode; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.MetaConstraint; @@ -119,6 +120,11 @@ private static Member getAccessible(Member original) { return original; } + SecurityManager sm = System.getSecurityManager(); + if ( sm != null ) { + sm.checkPermission( HibernateValidatorPermission.ACCESS_PRIVATE_MEMBERS ); + } + Class clazz = original.getDeclaringClass(); Member member; diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java index e996f7fd8c..2a4392e368 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java @@ -31,7 +31,6 @@ private GetDeclaredField(Class clazz, String fieldName) { public Field run() { try { final Field field = clazz.getDeclaredField( fieldName ); - field.setAccessible( true ); return field; } catch (NoSuchFieldException e) { diff --git a/tck-runner/src/test/resources/test.policy b/tck-runner/src/test/resources/test.policy index b2a4fbd1c6..fedfaede4e 100644 --- a/tck-runner/src/test/resources/test.policy +++ b/tck-runner/src/test/resources/test.policy @@ -28,6 +28,8 @@ grant codeBase "file:${localRepository}/org/hibernate/hibernate-validator/${proj permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.RuntimePermission "setContextClassLoader"; + permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; + // JAXB permission java.util.PropertyPermission "mapAnyUriToUri", "read"; }; @@ -39,6 +41,8 @@ grant codeBase "file:${basedir}/../engine/target/hibernate-validator-${project.v permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.RuntimePermission "setContextClassLoader"; + permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; + // JAXB permission java.util.PropertyPermission "mapAnyUriToUri", "read"; }; @@ -81,6 +85,7 @@ grant codeBase "file:${project.build.directory}/classes" { permission java.util.PropertyPermission "validation.provider", "read"; permission java.io.FilePermission "${localRepository}/org/hibernate/beanvalidation/tck/beanvalidation-tck-tests/${tck.version}/beanvalidation-tck-tests-${tck.version}.jar", "read"; permission java.util.PropertyPermission "user.language", "write"; + permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; }; grant codeBase "file:${project.build.directory}/test-classes" {