Top Description Inners Fields Constructors Methods
org.codehaus.groovy.control.customizers

public Class SecureASTCustomizer

extends CompilationCustomizer
Class Inheritance
Imports
org.codehaus.groovy.ast.ClassNode, .CodeVisitorSupport, .GroovyCodeVisitor, .ImportNode, .MethodNode, .ModuleNode, org.codehaus.groovy.ast.expr.ArgumentListExpression, .ArrayExpression, .AttributeExpression, .BinaryExpression, .BitwiseNegationExpression, .BooleanExpression, .CastExpression, .ClassExpression, .ClosureExpression, .ClosureListExpression, .ConstantExpression, .ConstructorCallExpression, .DeclarationExpression, .ElvisOperatorExpression, .Expression, .FieldExpression, .GStringExpression, .LambdaExpression, .ListExpression, .MapEntryExpression, .MapExpression, .MethodCallExpression, .MethodPointerExpression, .MethodReferenceExpression, .NotExpression, .PostfixExpression, .PrefixExpression, .PropertyExpression, .RangeExpression, .SpreadExpression, .SpreadMapExpression, .StaticMethodCallExpression, .TernaryExpression, .TupleExpression, .UnaryMinusExpression, .UnaryPlusExpression, .VariableExpression, org.codehaus.groovy.ast.stmt.AssertStatement, .BlockStatement, .BreakStatement, .CaseStatement, .CatchStatement, .ContinueStatement, .DoWhileStatement, .EmptyStatement, .ExpressionStatement, .ForStatement, .IfStatement, .ReturnStatement, .Statement, .SwitchStatement, .SynchronizedStatement, .ThrowStatement, .TryCatchStatement, .WhileStatement, org.codehaus.groovy.classgen.BytecodeExpression, .GeneratorContext, org.codehaus.groovy.control.CompilationFailedException, .CompilePhase, .SourceUnit, org.codehaus.groovy.syntax.Token, java.util.ArrayList, .Arrays, .Collections, .LinkedList, .List, .Map

This customizer allows securing source code by controlling what code constructs are permitted. This is typically done when using Groovy for its scripting or domain specific language (DSL) features. For example, if you only want to allow arithmetic operations in a groovy shell, you can configure this customizer to restrict package imports, method calls and so on.

Most of the security customization options found in this class work with either allowed or disallowed lists. This means that, for a single option, you can set an allowed list OR a disallowed list, but not both. You can mix allowed/disallowed strategies for different options. For example, you can have an allowed import list and a disallowed tokens list.

The recommended way of securing shells is to use allowed lists because it is guaranteed that future features of the Groovy language won't be accidentally allowed unless explicitly added to the allowed list. Using disallowed lists, you can limit the features of the language constructs supported by your shell by opting out, but new language features are then implicitly also available and this may not be desirable. The implication is that you might need to update your configuration with each new release.

If neither an allowed list nor a disallowed list is set, then everything is permitted.

Combinations of import and star import constraints are authorized as long as you use the same type of list for both. For example, you may use an import allowed list and a star import allowed list together, but you cannot use an import allowed list with a star import disallowed list. Static imports are handled separately, meaning that disallowing an import does not prevent from allowing a static import.

Eventually, if the features provided here are not sufficient, you may implement custom AST filtering handlers, either implementing the StatementChecker interface or ExpressionChecker interface then register your handlers thanks to the addExpressionCheckers(ExpressionChecker...) and addStatementCheckers(StatementChecker...) methods.

Here is an example of usage. We will create a groovy classloader which only supports arithmetic operations and imports the java.lang.Math classes by default.

final ImportCustomizer imports = new ImportCustomizer().addStaticStars('java.lang.Math') // add static import of java.lang.Math
final SecureASTCustomizer secure = new SecureASTCustomizer()
secure.with {
    closuresAllowed = false
    methodDefinitionAllowed = false

    allowedImports = []
    allowedStaticImports = []
    allowedStaticStarImports = ['java.lang.Math'] // only java.lang.Math is allowed

    allowedTokens = [
            PLUS,
            MINUS,
            MULTIPLY,
            DIVIDE,
            MOD,
            POWER,
            PLUS_PLUS,
            MINUS_MINUS,
            COMPARE_EQUAL,
            COMPARE_NOT_EQUAL,
            COMPARE_LESS_THAN,
            COMPARE_LESS_THAN_EQUAL,
            COMPARE_GREATER_THAN,
            COMPARE_GREATER_THAN_EQUAL,
    ].asImmutable()

    allowedConstantTypesClasses = [
            Integer,
            Float,
            Long,
            Double,
            BigDecimal,
            Integer.TYPE,
            Long.TYPE,
            Float.TYPE,
            Double.TYPE
    ].asImmutable()

    allowedReceiversClasses = [
            Math,
            Integer,
            Float,
            Double,
            Long,
            BigDecimal
    ].asImmutable()
}
CompilerConfiguration config = new CompilerConfiguration()
config.addCompilationCustomizers(imports, secure)
GroovyClassLoader loader = new GroovyClassLoader(this.class.classLoader, config)
 

Note

SecureASTCustomizer allows you to lock down the grammar of scripts but by itself isn't intended to be the complete solution of all security issues when running scripts on the JVM. You might also want to consider setting the groovy.grape.enable System property to false, augmenting use of the customizer with additional techniques, and following standard security principles for JVM applications.

For more information, please read:

  • Improved sandboxing of Groovy scripts
  • Oracle's Secure Coding Guidelines
  • 10 Java security best practices
  • Thirteen rules for developing secure Java applications
  • 12 Java Security Best Practices
  • Since
    1.8.0

    Nested and Inner Type Summary

    Modifier and TypeClass and Description
    public static interface
    SecureASTCustomizer.ExpressionChecker

    This interface allows the user to provide a custom expression checker if the dis/allowed expression lists are not sufficient

    protected class
    SecureASTCustomizer.SecuringCodeVisitor

    This visitor directly implements the GroovyCodeVisitor interface instead of using the CodeVisitorSupport class to make sure that future features of the language gets managed by this visitor.

    public static interface
    SecureASTCustomizer.StatementChecker

    This interface allows the user to provide a custom statement checker if the dis/allowed statement lists are not sufficient

    Field Summary

    Modifier and TypeField and Description
    private List<String>
    private List<Class<? extends Expression>>
    private List<String>
    private List<String>
    private List<String>
    private List<Class<? extends Statement>>
    private List<String>
    private List<String>
    private List<Integer>
    private List<String>
    private List<Class<? extends Expression>>
    private List<String>
    private List<String>
    private List<String>
    private List<Class<? extends Statement>>
    private List<String>
    private List<String>
    private List<Integer>
    private final List<SecureASTCustomizer.ExpressionChecker>
    private boolean
    private boolean
    private boolean
    private boolean
    private final List<SecureASTCustomizer.StatementChecker>

    Constructor Summary

    AccessConstructor and Description
    public

    Method Summary

    Modifier and TypeMethod and Description
    public void
    public void
    protected void
    assertImportIsAllowed(final String className)

    protected void
    assertStarImportIsAllowed(final String packageName)

    protected void
    assertStaticImportIsAllowed(final String member, final String className)

    public void
    protected void
    protected GroovyCodeVisitor
    protected static List<MethodNode>
    public List<String>
    public List<Class<? extends Expression>>
    public List<String>
    public List<String>
    public List<String>
    public List<Class<? extends Statement>>
    public List<String>
    public List<String>
    public List<Integer>
    public List<String>
    public List<String>
    public List<String>
    public List<Class<? extends Expression>>
    public List<String>
    public List<String>
    public List<String>
    public List<Class<? extends Statement>>
    public List<String>
    public List<String>
    public List<Integer>
    public List<Class<? extends Expression>>
    public List<Class<? extends Expression>>
    public List<String>
    public List<String>
    public List<String>
    public List<String>
    public List<String>
    public List<String>
    public List<Class<? extends Statement>>
    public List<Class<? extends Statement>>
    public List<String>
    public List<String>
    public List<String>
    public List<String>
    public List<Integer>
    public List<Integer>
    private String
    public boolean
    public boolean
    public boolean
    public boolean
    private static List<String>
    public void
    setAllowedConstantTypes(final List<String> allowedConstantTypes)

    public void
    setAllowedConstantTypesClasses(final List<Class<T>>
    a list of classes.
    allowedConstantTypes
    )

    An alternative way of setting constant types.

    public void
    setAllowedExpressions(final List<Class<? extends Expression>> allowedExpressions)

    public void
    setAllowedImports(final List<String> allowedImports)

    public void
    setAllowedReceivers(final List<String>
    the list of accepted classes, as fully qualified names
    allowedReceivers
    )

    Sets the list of classes which may accept method calls.

    public void
    setAllowedReceiversClasses(final List<Class<T>>
    a list of classes.
    allowedReceivers
    )

    An alternative way of setting receiver classes.

    public void
    setAllowedStarImports(final List<String> allowedStarImports)

    public void
    setAllowedStatements(final List<Class<? extends Statement>> allowedStatements)

    public void
    setAllowedStaticImports(final List<String> allowedStaticImports)

    public void
    setAllowedStaticStarImports(final List<String> allowedStaticStarImports)

    public void
    setAllowedTokens(final List<Integer>
    the tokens. The values of the tokens must be those of org.codehaus.groovy.syntax.Types
    allowedTokens
    )

    Sets the list of tokens which are permitted.

    public void
    setClosuresAllowed(final boolean closuresAllowed)

    public void
    setConstantTypesBlackList(final List<String> constantTypesBlackList)

    public void
    setConstantTypesClassesBlackList(final List<Class<T>> disallowedConstantTypes)

    Legacy alias for setDisallowedConstantTypesClasses(List)

    public void
    setConstantTypesClassesWhiteList(final List<Class<T>> allowedConstantTypes)

    Legacy alias for setAllowedConstantTypesClasses(List)

    public void
    setConstantTypesWhiteList(final List<String> allowedConstantTypes)

    Legacy alias for setAllowedConstantTypes(List)

    public void
    setDisallowedConstantTypesClasses(final List<Class<T>>
    a list of classes.
    disallowedConstantTypes
    )

    An alternative way of setting constant types.

    public void
    setDisallowedExpressions(final List<Class<? extends Expression>> disallowedExpressions)

    public void
    setDisallowedImports(final List<String> disallowedImports)

    public void
    setDisallowedReceivers(final List<String>
    the list of refused classes, as fully qualified names
    disallowedReceivers
    )

    Sets the list of classes which deny method calls.

    public void
    setDisallowedReceiversClasses(final List<Class<T>>
    a list of classes.
    disallowedReceivers
    )

    An alternative way of setting receiver classes.

    public void
    setDisallowedStarImports(final List<String> disallowedStarImports)

    public void
    setDisallowedStatements(final List<Class<? extends Statement>> disallowedStatements)

    public void
    setDisallowedStaticImports(final List<String> disallowedStaticImports)

    public void
    setDisallowedStaticStarImports(final List<String> disallowedStaticStarImports)

    public void
    setDisallowedTokens(final List<Integer>
    the tokens. The values of the tokens must be those of org.codehaus.groovy.syntax.Types
    disallowedTokens
    )

    Sets the list of tokens which are not permitted.

    public void
    setExpressionsBlacklist(final List<Class<? extends Expression>> disallowedExpressions)

    Legacy alias for setDisallowedExpressions(List)

    public void
    setExpressionsWhitelist(final List<Class<? extends Expression>> allowedExpressions)

    Legacy alias for setAllowedExpressions(List)

    public void
    setImportsBlacklist(final List<String> disallowedImports)

    Legacy alias for setDisallowedImports(List)

    public void
    setImportsWhitelist(final List<String> allowedImports)

    Legacy alias for setAllowedImports(List)

    public void
    setIndirectImportCheckEnabled(final boolean
    set to true to enable indirect checks
    indirectImportCheckEnabled
    )

    Set this option to true if you want your import rules to be checked against every class node.

    public void
    setMethodDefinitionAllowed(final boolean methodDefinitionAllowed)

    public void
    setPackageAllowed(final boolean packageAllowed)

    public void
    setReceiversBlackList(final List<String> disallowedReceivers)

    Legacy alias for setDisallowedReceivers(List)

    public void
    setReceiversClassesBlackList(final List<Class<T>> disallowedReceivers)

    Legacy alias for setDisallowedReceiversClasses(List).

    public void
    setReceiversClassesWhiteList(final List<Class<T>> allowedReceivers)

    Legacy alias for setAllowedReceiversClasses(List)

    public void
    setReceiversWhiteList(final List<String> allowedReceivers)

    Legacy alias for setAllowedReceivers(List)

    public void
    setStarImportsBlacklist(final List<String> disallowedStarImports)

    Legacy alias for setDisallowedStarImports(List)

    public void
    setStarImportsWhitelist(final List<String> allowedStarImports)

    Legacy alias for setAllowedStarImports(List)

    public void
    setStatementsBlacklist(final List<Class<? extends Statement>> disallowedStatements)

    Legacy alias for setDisallowedStatements(List)

    public void
    setStatementsWhitelist(final List<Class<? extends Statement>> allowedStatements)

    Legacy alias for setAllowedStatements(List)

    public void
    setStaticImportsBlacklist(final List<String> disallowedStaticImports)

    Legacy alias for setDisallowedStaticImports(List)

    public void
    setStaticImportsWhitelist(final List<String> allowedStaticImports)

    Legacy alias for setAllowedStaticImports(List)

    public void
    setStaticStarImportsBlacklist(final List<String> disallowedStaticStarImports)

    Legacy alias for setDisallowedStaticStarImports(List)

    public void
    setStaticStarImportsWhitelist(final List<String> allowedStaticStarImports)

    Legacy alias for setAllowedStaticStarImports(List)

    public void
    setTokensBlacklist(final List<Integer> disallowedTokens)

    Alias for setDisallowedTokens(List).

    public void
    setTokensWhitelist(final List<Integer> allowedTokens)

    Legacy alias for setAllowedTokens(List)

    Inherited from org.codehaus.groovy.control.customizers.CompilationCustomizer:
    getPhase