Class SandboxTransformer
- All Implemented Interfaces:
org.codehaus.groovy.control.CompilationUnit.IPrimaryClassNodeOperation
Sometimes you'd like to run Groovy scripts in a sandbox environment, where you only want it to access limited subset of the rest of JVM. This transformation makes that possible by letting you inspect every step of the script execution when it makes method calls and property/field/array access.
Once the script is transformed, every intercepted operation results in a call to Checker,
which further forwards the call to GroovyInterceptor for inspection.
To use it, add it to the CompilerConfiguration, like this:
def cc = new CompilerConfiguration() cc.addCompilationCustomizers(new SandboxTransformer()) sh = new GroovyShell(cc)
By default, this code intercepts everything that can be intercepted, which are:
- Method calls (instance method and static method)
- Object allocation (that is, a constructor call except of the form "this(...)" and "super(...)")
- Property access (e.g., z=foo.bar, z=foo."bar") and assignment (e.g., foo.bar=z, foo."bar"=z)
- Attribute access (e.g., z=foo.@bar) and assignments (e.g., foo.@bar=z)
- Array access and assignment (z=x[y] and x[y]=z)
You can disable interceptions selectively by setting respective interceptXXX flags to false.
There'll be a substantial hit to the performance of the execution.
- Author:
- Kohsuke Kawaguchi
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidcall(org.codehaus.groovy.control.SourceUnit source, org.codehaus.groovy.classgen.GeneratorContext context, org.codehaus.groovy.ast.ClassNode classNode) org.codehaus.groovy.ast.ClassCodeExpressionTransformercreateVisitor(org.codehaus.groovy.control.SourceUnit source) Deprecated.org.codehaus.groovy.ast.ClassCodeExpressionTransformercreateVisitor(org.codehaus.groovy.control.SourceUnit source, org.codehaus.groovy.ast.ClassNode clazz) voidforbidIfFinalizer(org.codehaus.groovy.ast.MethodNode m) Object.finalize()is called by the JVM outside of the sandbox, so overriding it in a sandboxed script is not allowed.static booleanmightBePositionalArgumentConstructor(org.codehaus.groovy.ast.expr.VariableExpression ve) Checks if aDeclarationExpression.getVariableExpression()might induceDefaultTypeTransformation.castToType(java.lang.Object, java.lang.Class)to call a constructor.voidprocessConstructors(org.codehaus.groovy.ast.ClassCodeExpressionTransformer visitor, org.codehaus.groovy.ast.ClassNode classNode) Apply SECURITY-582 (and part of SECURITY-1754) fix to constructors.Methods inherited from class org.codehaus.groovy.control.customizers.CompilationCustomizer
getPhaseMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.codehaus.groovy.control.CompilationUnit.IPrimaryClassNodeOperation
doPhaseOperation, needSortedInput
-
Constructor Details
-
SandboxTransformer
public SandboxTransformer()
-
-
Method Details
-
call
public void call(org.codehaus.groovy.control.SourceUnit source, org.codehaus.groovy.classgen.GeneratorContext context, org.codehaus.groovy.ast.ClassNode classNode) -
forbidIfFinalizer
public void forbidIfFinalizer(org.codehaus.groovy.ast.MethodNode m) Object.finalize()is called by the JVM outside of the sandbox, so overriding it in a sandboxed script is not allowed. -
processConstructors
public void processConstructors(org.codehaus.groovy.ast.ClassCodeExpressionTransformer visitor, org.codehaus.groovy.ast.ClassNode classNode) Apply SECURITY-582 (and part of SECURITY-1754) fix to constructors. For example, given code like this:class B { } class A extends B { A(T1 p1, ..., TM pM) { super(U1 a1, ..., UN aN) // or `this(...)` ... } }processConstructors(org.codehaus.groovy.ast.ClassCodeExpressionTransformer, org.codehaus.groovy.ast.ClassNode)will transform it into something like this:class B { } class A extends B { A(T1 p1, ..., TM pM) { this(Checker.checkedSuperConstructor( // or `Checker.checkedThisConstructor` B.class, new Object[]{a1, ..., aN}, new Object[]{p1, ..., pM}, new Class<?>[]{SuperConstructorWrapper.class, T1.class, ..., TM.class}), // or `ThisConstructorWrapper.class` p1, ..., pM) } A(Checker.SuperConstructorWrapper $cw, T1 p1, ..., TM pM) { // Or `Checker.ThisConstructorWrapper $cw` super($cw.arg(1), ... cw.arg(N)) // or `this(...)` ... } } -
createVisitor
@Deprecated public org.codehaus.groovy.ast.ClassCodeExpressionTransformer createVisitor(org.codehaus.groovy.control.SourceUnit source) Deprecated. -
createVisitor
public org.codehaus.groovy.ast.ClassCodeExpressionTransformer createVisitor(org.codehaus.groovy.control.SourceUnit source, org.codehaus.groovy.ast.ClassNode clazz) -
mightBePositionalArgumentConstructor
public static boolean mightBePositionalArgumentConstructor(org.codehaus.groovy.ast.expr.VariableExpression ve) Checks if aDeclarationExpression.getVariableExpression()might induceDefaultTypeTransformation.castToType(java.lang.Object, java.lang.Class)to call a constructor. If so,Checker.checkedCast(java.lang.Class<?>, java.lang.Object, boolean, boolean, boolean)should be run. Will be false for example if the declared type is an array,abstract, or unspecified (justdef). Not yet supportingDeclarationExpression.getTupleExpression()on LHS; and currently ignoringBinaryExpression.getRightExpression()though some might not possibly be arrays,Collections, orMaps.
-