Skip to content

Conversation

@duoduobingbing
Copy link

@duoduobingbing duoduobingbing commented Jun 17, 2023

This PR outsources the public methods of ExpressionUtils to a dedicated class StandardExpressionClassAccessEvaluator that implements a new interface IStandardExpressionClassAccessEvaluator.

Thus it now becomes possible for a user to provide a custom implementation of IExpressionClassAccessEvaluator that can be supplied to the acting TemplateEngine e.g. like

@Bean
public SpringTemplateEngine templateEngine() {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    //... other setup
    templateEngine.setExpressionClassAccessEvaluator(new CustomExpressionClassAccessEvaluator());
    return templateEngine;
}

By default (= when the user not explicitly sets a different IExpressionClassAccessEvaluator for the acting TemplateEngine) the implementation StandardExpressionClassAccessEvaluator with sensible defaults will be used that most likely fits most use-cases and provides the current behavior.

But for cases where more control over this behavior is needed e.g.

  • to allow classes like java.util.concurrent.atomic.AtomicBoolean that might be used in a template because it is deemed safe for the used context or
  • to implement an even stricter paradigm of what is being blocked, like for example disallowing all classes that are not written by the user, e.g. only allowing my.custom.example.*

the mechanism introduced in this PR can be leveraged by a user of Thymeleaf.

Fixes #829

Alternatives

An alternative is to introduce a method on the templating engine to specifially set packages and classes to allow or deny e.g. something like

//..
templateEngine.setAllowDenyClassExpressionBehavior(
                BehaviorType.DENYLIST, 
                (configurer) -> 
                             configurer.addPackage("java").addExclusions(
                                            (exclusion) -> exclusion
                                                            .addSubpackages("java.time")
                                                            .addClasses(Boolean.class, Byte.class)
                                                            .addSuperclasses(Collection.class, Stream.class)
                                             )
                             .addClass(PotentiallyDangerous.class)
                             .addSuperclass(DangerousSuperclass.class)
);
//..

to disallow everything from java and its subpackages except everything from java.time, Boolean, Byte and all implementations of Collection and Stream, disallow PotentiallyDangerous and disallow DangerousSuperclass and all descendents of it.

However in the current behavior ExpressionUtils contains perfomance fixes, that would have to be removed in order to make this work. To give users the ability to provide their own performance fixes, IExpressionClassAccessEvaluator was chosen as an approach for this PR to make the allowed and denied classes configurable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add AllowList for classes that should be available for static access via T() in sensitive expressions

1 participant