Skip to content
corinnekrych edited this page Jan 19, 2014 · 49 revisions

#Tasks WL = WhiteList BL = BlackList

Name Description Status Link
testMethodInScript Method in script WL/BL : a method defined in a script DONE testMethodInScript
testMethodInsideMethod Method inside another method WL/BL : imbrication of methods DONE testMethodInsideMethod
testMethodAsArguments Method as argument of another method WL/BL : Imbrication of methods DONE testMethodAsArguments
testMethodAsARightBinaryExpression Method within a Binary exp WL/BL like: a.add(new ArrayList().clear() + "") DONE testMethodAsARightBinaryExpression
testMethodAsLeftBinaryExpression Method within a Binary exp WL/BL like: a.add(new ArrayList().clear() + "") DONE testMethodAsLeftBinaryExpression
testMethodDefinedInScript Method defined within script but not in white list should not throw exception DONE testMethodDefinedInScript
testClosureDefinedInScript Closure within script but not in white list TODO testClosureDefinedInScript
testStaticMethodDefinedInScript Static method defined within script but not in white list should not throw exception DONE testStaticMethodDefinedInScript
testStaticMethodInBlackList Test we're going into StaticMethodCallExpression as Math.random goes through MethodCallExpression. This BL doesn't make any sense DONE testStaticMethodInBlackList
testForNameSecurity Test WL BL with different ways of instantiate an object @Newify, introspection DONE testForNameSecurity
testForNameSecurityNewify Test WL BL with different ways of instantiate an object @Newify, introspection DONE testForNameSecurityNewify
testForNameSecurityFromInt Test WL BL with different ways of instantiate an object @Newify, introspection DONE testForNameSecurityFromInt
testMethodCallInClassDefinedInScript Defined a class in script, within its method, BL/WL method call DONE testMethodCallInClassDefinedInScript
testConstructorWithClassForName Introspection, blacklist forName TODO testConstructorWithClassForName
testConstructorWithClass ForNameComingFromAnotherClass Introspection, blacklist forName where class comes from an obeject TODO testConstructorWithClass ForNameComingFromAnotherClass
testSimpleConstructor Introspection, blacklist forName where class comes from an obeject DONE testSimpleConstructor
testConstructorWithNewify Construction with annotation newify TODO testConstructorWithNewify
testIfStatementForRuntime Blacklist method call in if statement DONE testIfStatementForRuntime
testReturnStatementForRuntime Blacklist method call in return statement DONE testReturnStatementForRuntime
testMethodCallAsString Method call as a string DONE testMethodCallAsString
testMethodInArrayInititalization Method call in array initialization DONE testMethodInArrayInititalization
testAlias alias DONE testAlias
testMethodChain Chaining method call #2 testMethodChain
testStaticImport Method call with static import DONE testStaticImport
testClassGetName BL/WL getCLass() On Going testClassGetName
testClassGetName2 BL/WL getCLass().getName() On Going testClassGetName2
testPropertyDirectGet Direct property get with @ TODO testPropertyDirectGet
testPropertySet Property set TODO testPropertySet
testAttributeSet Direct attribute set with @ TODO testAttributeSet
testSpreadOperator Spread operator DONE testSpreadOperator
testArrayGet Access array with bracket TODO testArrayGet
testArraySet Access array with bracket TODO testArraySet
testInnerClass BL WL method call within an inner Class DONE testInnerClass
testStaticInitializationBlock Static init block DONE testStaticInitializationBlock
testInitializationBlock Init block DONE testInitializationBlock
testFieldInitialization Inline initialization of attribute DONE testFieldInitialization
testStaticFieldInitialization Inline initialization of static attribute DONE testStaticFieldInitialization
testNestedClass Anonymous class FABRICE testNestedClass
testCompoundAssignmentOnArray intArray[1] <<= 3 (compound assignment) TODO testCompoundAssignmentOnArray
testComparisonPrimitives 7==7 #3 testComparisonPrimitives
testComparisonObject compare object TODO testComparisonObject
testNullBehavior Null?? TODO testNullBehavior
list different class construction forNames @newify etc... .. TODO ..
groovyAccessControl groovyAccessControl defines in all scripts classes, how to define it one time only .. ..
Documentation .. TODO ..
CompileTime no specific test Compile time method granularity: instead of having methodsWhiteList defined in SecureRuntimeASTCustomizer move it to its based class SecureASTCustomizer Ongoing branch compiletime
Constant Anything to do?? TODO ..
Custom Checker Let the user defines is own class to validate a method call. Extendable interface. Ongoing branch checker2
Constant Anything to do?? TODO ..
Hierarchy BL like Object.toString() TODO ..
setSource in all transformation Take all 'DONE' test DONE ..
Replace new ClassNode by ClassHelper.make See Cedric workshop for best practise DONE ..

#Design for the HackenGarten How to secure your Groovy script?

##Using SecureASTCustomizer at compile time ###What is it? When evaluating a script in Groovy you have the option to use AST to transform your script. You can do it using Customizer. As the name said it all, it allows you to customize your script. Among well know existing Customizer you may have used ImportCustomizer, etc.. To secure your script at compile time you can use SecureASTCustomizer as shown below:

import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.SecureASTCustomizer

def configuration = new CompilerConfiguration()
def customizer = new SecureASTCustomizer()
customizer.with {
   setReceiversBlackList(["java.lang.System"])
}
configuration.addCompilationCustomizers(customizer)
new GroovyShell(configuration).evaluate('''
    System.exit(-1)
''')

This will throw a SecurityException at compile time telling you that you are not authorised to use System.

###Limitations:

This has a huge limitation : Groovy is a dynamic language

import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.SecureASTCustomizer

def configuration = new CompilerConfiguration()
def customizer = new SecureASTCustomizer()
customizer.with {
   setReceiversBlackList(["java.lang.System"])
}
configuration.addCompilationCustomizers(customizer)
new GroovyShell(configuration).evaluate('''
   ((Object)System).exit(-1)
''')

This will run and exit !

##Securing runtime solutions

There are already a few implementations that provide runtime security check either at skin level (only checking that a call inside your script is accepted) or deep level (checking that the call stack is accepted)

  1. SandBox from Kohsuke.

  2. Simon Temple's blog

  3. JavaSandbox

This ones involved Security Manager implementation for deep level security.

##What we want to add ###SecureRuntimeASTCustomizer class diagram

This solution is highly inspired from Groovy Sandbox and Simon's solution but will wrap the intercepted call inside a closure to be as Groovy as possible and will be forward compatible with evolution.

The existing solutions are great but they are too intrusive (especially on the Groovy way to invoke a method). The Groovy sandbox is the most advanced one but is also the most intrusive by trying to replicate call site caching mechanism and probably using class and method that could be modified or deleted in the future.

The solution we propose is to wrap the intercepted call within a closure. It has the advantage to be more compatible with call site, static typing or invoke dynamic.

Intercepting Groovy calls, however, have a performance impact on script execution. ###SecureRuntimeASTCustomizer with Checker module class diagram

A variant of the SecureRuntimeASTCustomizer (see checker2 branch) could be to let the user decide which Checker he wants to use or even better let him add as many Checkers he wants. In order to achieve this design, the challenge is how to inject those at compile time and use them at runtime.

This is the reason why we define 2 interfaces: Checker and MethodChecker (other will be implemented). GroovyAccessControl is responsible to create the Checker using the injectCheckerASTConstructor method using getConfigurationList from the interface.

At runtime, we wrap the expression within a groovyAccessControl.checkMethodCall(object, method, args, closure). GroovyAccessControl has a list of all checkers and call isAllowed on each of them.

#References

Clone this wiki locally