瀏覽代碼

Add sandboxing for GString-based method invocation

Lee Hinman 11 年之前
父節點
當前提交
47856ec4cd

+ 6 - 1
src/main/java/org/elasticsearch/script/groovy/GroovySandboxExpressionChecker.java

@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableSet;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
 import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.GStringExpression;
 import org.codehaus.groovy.ast.expr.MethodCallExpression;
 import org.codehaus.groovy.control.customizers.SecureASTCustomizer;
 import org.elasticsearch.common.settings.Settings;
@@ -115,7 +116,11 @@ public class GroovySandboxExpressionChecker implements SecureASTCustomizer.Expre
     public boolean isAuthorized(Expression expression) {
         if (expression instanceof MethodCallExpression) {
             MethodCallExpression mce = (MethodCallExpression) expression;
-            if (methodBlacklist.contains(mce.getMethodAsString())) {
+            String methodName = mce.getMethodAsString();
+            if (methodBlacklist.contains(methodName)) {
+                return false;
+            } else if (methodName == null && mce.getMethod() instanceof GStringExpression) {
+                // We do not allow GStrings for method invocation, they are a security risk
                 return false;
             }
         } else if (expression instanceof ConstructorCallExpression) {

+ 7 - 0
src/test/java/org/elasticsearch/script/GroovySandboxScriptTests.java

@@ -55,6 +55,10 @@ public class GroovySandboxScriptTests extends ElasticsearchIntegrationTest {
         testFailure("d = new DateTime(); d.getClass().getDeclaredMethod(\\\"plus\\\").setAccessible(true)",
                 "Expression [MethodCallExpression] is not allowed: d.getClass()");
 
+        testFailure("d = new DateTime(); d.\\\"${'get' + 'Class'}\\\"()." +
+                        "\\\"${'getDeclared' + 'Method'}\\\"(\\\"now\\\").\\\"${'set' + 'Accessible'}\\\"(false)",
+                "Expression [MethodCallExpression] is not allowed: d.$(get + Class)().$(getDeclared + Method)(now).$(set + Accessible)(false)");
+
         testFailure("Class.forName(\\\"DateTime\\\").getDeclaredMethod(\\\"plus\\\").setAccessible(true)",
                 "Method calls not allowed on [java.lang.Class]");
 
@@ -79,6 +83,9 @@ public class GroovySandboxScriptTests extends ElasticsearchIntegrationTest {
                 "Importing [java.util.concurrent.ThreadPoolExecutor] is not allowed");
 
         testFailure("s = new java.net.URL();", "Expression [ConstructorCallExpression] is not allowed: new java.net.URL()");
+
+        testFailure("def methodName = 'ex'; Runtime.\\\"${'get' + 'Runtime'}\\\"().\\\"${methodName}ec\\\"(\\\"touch /tmp/gotcha2\\\")",
+                "Expression [MethodCallExpression] is not allowed: java.lang.Runtime.$(get + Runtime)().$methodNameec(touch /tmp/gotcha2)");
     }
 
     public void testSuccess(String script) {