Skip to content

Commit

Permalink
Modified expression restrictions
Browse files Browse the repository at this point in the history
  • Loading branch information
danielfernandez committed Apr 18, 2023
1 parent a05bfa0 commit dd01397
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 43 deletions.
Expand Up @@ -48,7 +48,7 @@
public final class ExpressionUtils {


// NOTE thes lists are hard-wired into code, so any change to these sets should be synchronized with changes
// NOTE these lists are hard-wired into code, so any change to these sets should be synchronized with changes
// in the corresponding code for quickly checking the fact that a type name might be in the blocking list.
private static final Set<String> BLOCKED_ALL_PURPOSES_PACKAGE_NAME_PREFIXES =
new HashSet<>(Arrays.asList(
Expand All @@ -65,7 +65,10 @@ public final class ExpressionUtils {
"javassist.", "javax0.geci.",
"org.apache.bcel.", "org.aspectj.", "org.javassist.", "org.mockito.", "org.objectweb.asm.",
"org.objenesis.", "org.springframework.aot.", "org.springframework.asm.",
"org.springframework.cglib.", "org.springframework.javapoet.", "org.springframework.objenesis."));
"org.springframework.cglib.", "org.springframework.javapoet.", "org.springframework.objenesis.",
"org.springframework.web.", "org.springframework.webflow.", "org.springframework.context.",
"org.springframework.beans.", "org.springframework.aspects.", "org.springframework.aop.",
"org.springframework.expression."));


private static final Set<String> ALLOWED_JAVA_CLASS_NAMES;
Expand All @@ -88,10 +91,33 @@ public final class ExpressionUtils {
Collection.class, Iterable.class, List.class, Map.class, Map.Entry.class, Set.class,
Calendar.class, Stream.class));

private static final Set<String> BLOCKED_MEMBER_CALL_JAVA_SUPERS_NAMES =
new HashSet<>(Arrays.asList(
// org.thymeleaf
"org.thymeleaf.standard.expression.IStandardVariableExpressionEvaluator",
"org.thymeleaf.standard.expression.IStandardExpressionParser",
"org.thymeleaf.standard.expression.IStandardConversionService",
"org.thymeleaf.spring5.context.IThymeleafRequestContext",
"org.thymeleaf.spring5.expression.IThymeleafEvaluationContext",
"org.thymeleaf.spring6.context.IThymeleafRequestContext",
"org.thymeleaf.spring6.expression.IThymeleafEvaluationContext",
// org.springframework
"org.springframework.web.servlet.support.RequestContext",
"org.springframework.web.reactive.result.view.RequestContext"));
private static final Set<Class<?>> BLOCKED_MEMBER_CALL_JAVA_SUPERS;


static {
ALLOWED_JAVA_CLASS_NAMES = ALLOWED_JAVA_CLASSES.stream().map(c -> c.getName()).collect(Collectors.toSet());
ALLOWED_JAVA_SUPERS_NAMES = ALLOWED_JAVA_SUPERS.stream().map(c -> c.getName()).collect(Collectors.toSet());
BLOCKED_MEMBER_CALL_JAVA_SUPERS = BLOCKED_MEMBER_CALL_JAVA_SUPERS_NAMES.stream().
map(className -> {
try {
return Optional.of(Class.forName(className));
} catch (final ClassNotFoundException e) {
return Optional.ofNullable((Class<?>)null);
}
}).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toSet());
}


Expand Down Expand Up @@ -122,7 +148,7 @@ static boolean isJavaPackage(final String typeName) {
&& typeName.charAt(2) == 'v' && typeName.charAt(3) == 'a');
}

static boolean isPackageBlockedForAllPurposes(final String typeName) {
static boolean isTypeBlockedForAllPurposes(final String typeName) {
final char c0 = typeName.charAt(0);
if (c0 != 'c' && c0 != 'j' && c0 != 'o' && c0 != 's'){ // All blocked packages start with: c, j, o, s
return false;
Expand All @@ -136,8 +162,8 @@ static boolean isPackageBlockedForAllPurposes(final String typeName) {
return BLOCKED_ALL_PURPOSES_PACKAGE_NAME_PREFIXES.stream().anyMatch(prefix -> typeName.startsWith(prefix));
}

static boolean isPackageBlockedForTypeReference(final String typeName) {
if (isPackageBlockedForAllPurposes(typeName)) {
static boolean isTypeBlockedForTypeReference(final String typeName) {
if (isTypeBlockedForAllPurposes(typeName)) {
return true;
}
final char c0 = typeName.charAt(0);
Expand All @@ -158,7 +184,7 @@ public static boolean isTypeAllowed(final String typeName) {

final String normalizedTypeName = normalize(typeName);

if (!isPackageBlockedForTypeReference(normalizedTypeName)) {
if (!isTypeBlockedForTypeReference(normalizedTypeName)) {
return true;
}

Expand All @@ -169,13 +195,18 @@ public static boolean isTypeAllowed(final String typeName) {



static boolean isTypeBlockedForMemberCalls(final Class<?> type) {
return BLOCKED_MEMBER_CALL_JAVA_SUPERS.stream().anyMatch(i -> i.isAssignableFrom(type));
}


static boolean isMemberAllowedForInstanceOfType(final Class<?> type, final String memberName) {

Validate.notNull(type, "Type cannot be null");

final String typeName = type.getName();

if (!isPackageBlockedForAllPurposes(typeName)) {
if (!isTypeBlockedForAllPurposes(typeName) && !isTypeBlockedForMemberCalls(type)) {
return true;
}

Expand Down
Expand Up @@ -45,46 +45,46 @@ public final class ExpressionUtilsTest {

@Test
public void typeBlockedForAllPurposesTest() {
Assertions.assertFalse(isPackageBlockedForAllPurposes("org.thymeleaf.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("org.springframework.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("org.springframework.cglib.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("org.springframework.aot.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("org.springframework.javapoet.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("net.bytebuddy.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("es.whatever.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("de.whatever.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("net.whatever.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("org.whatever.X"));
Assertions.assertTrue(isPackageBlockedForAllPurposes("java.lang.X"));
Assertions.assertTrue(isPackageBlockedForAllPurposes("java.lang.Runtime"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("java.time.X"));
Assertions.assertTrue(isPackageBlockedForAllPurposes("javax.servlet.X"));
Assertions.assertTrue(isPackageBlockedForAllPurposes("jakarta.servlet.X"));
Assertions.assertFalse(isPackageBlockedForAllPurposes("com.whatever.X"));
Assertions.assertTrue(isPackageBlockedForAllPurposes("com.sun.X"));
Assertions.assertTrue(isPackageBlockedForAllPurposes("jdk.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("org.thymeleaf.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("org.springframework.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("org.springframework.cglib.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("org.springframework.aot.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("org.springframework.javapoet.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("net.bytebuddy.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("es.whatever.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("de.whatever.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("net.whatever.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("org.whatever.X"));
Assertions.assertTrue(isTypeBlockedForAllPurposes("java.lang.X"));
Assertions.assertTrue(isTypeBlockedForAllPurposes("java.lang.Runtime"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("java.time.X"));
Assertions.assertTrue(isTypeBlockedForAllPurposes("javax.servlet.X"));
Assertions.assertTrue(isTypeBlockedForAllPurposes("jakarta.servlet.X"));
Assertions.assertFalse(isTypeBlockedForAllPurposes("com.whatever.X"));
Assertions.assertTrue(isTypeBlockedForAllPurposes("com.sun.X"));
Assertions.assertTrue(isTypeBlockedForAllPurposes("jdk.X"));
}

@Test
public void typeBlockedForTypeReferenceTest() {
Assertions.assertFalse(isPackageBlockedForTypeReference("org.thymeleaf.X"));
Assertions.assertFalse(isPackageBlockedForTypeReference("org.springframework.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("org.springframework.cglib.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("org.springframework.aot.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("org.springframework.javapoet.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("net.bytebuddy.X"));
Assertions.assertFalse(isPackageBlockedForTypeReference("es.whatever.X"));
Assertions.assertFalse(isPackageBlockedForTypeReference("de.whatever.X"));
Assertions.assertFalse(isPackageBlockedForTypeReference("net.whatever.X"));
Assertions.assertFalse(isPackageBlockedForTypeReference("org.whatever.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("java.lang.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("java.lang.Runtime"));
Assertions.assertFalse(isPackageBlockedForTypeReference("java.time.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("javax.servlet.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("jakarta.servlet.X"));
Assertions.assertFalse(isPackageBlockedForTypeReference("com.whatever.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("com.sun.X"));
Assertions.assertTrue(isPackageBlockedForTypeReference("jdk.X"));
Assertions.assertFalse(isTypeBlockedForTypeReference("org.thymeleaf.X"));
Assertions.assertFalse(isTypeBlockedForTypeReference("org.springframework.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("org.springframework.cglib.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("org.springframework.aot.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("org.springframework.javapoet.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("net.bytebuddy.X"));
Assertions.assertFalse(isTypeBlockedForTypeReference("es.whatever.X"));
Assertions.assertFalse(isTypeBlockedForTypeReference("de.whatever.X"));
Assertions.assertFalse(isTypeBlockedForTypeReference("net.whatever.X"));
Assertions.assertFalse(isTypeBlockedForTypeReference("org.whatever.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("java.lang.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("java.lang.Runtime"));
Assertions.assertFalse(isTypeBlockedForTypeReference("java.time.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("javax.servlet.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("jakarta.servlet.X"));
Assertions.assertFalse(isTypeBlockedForTypeReference("com.whatever.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("com.sun.X"));
Assertions.assertTrue(isTypeBlockedForTypeReference("jdk.X"));
}

@Test
Expand Down

0 comments on commit dd01397

Please sign in to comment.