Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft generator #53

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ Groovy policy comes with a native sandbox feature allowing to safely run Groovy
predefined list of allowed methods, fields, constructors, and annotations.

The complete whitelist can be found here : https://raw.githubusercontent.com/gravitee-io/gravitee-policy-groovy/master/src/main/resources/groovy-whitelist[gravitee groovy whitelist]
The whitelist is generated with an executable `src/test/java/io/gravitee/policy/groovy/exec/GroovyWhitelistGenerator.java`, we can launch `mvn exec:java` to regenerate.

This whitelist should be enough for almost all possible use cases. If you have specific needs which are not allowed by the built-in whitelist, you can extend (or even replace) the list with your own declarations.
For that, you can configure the gravitee.yml by specifying:
Expand Down
13 changes: 11 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
<gravitee-gateway-buffer.version>1.18.3</gravitee-gateway-buffer.version>
<gravitee-policy-api.version>1.9.0</gravitee-policy-api.version>
<gravitee-common.version>1.17.2</gravitee-common.version>
<groovy.version>3.0.9</groovy.version>
<groovy.version>3.0.10</groovy.version>
<groovy-sandbox.version>1.27</groovy-sandbox.version>
<commons-lang3.version>3.11</commons-lang3.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<guava.version>30.1.1-jre</guava.version>
<maven-assembly-plugin.version>2.5.5</maven-assembly-plugin.version>
<!-- Property used by the publication job in CI-->
Expand Down Expand Up @@ -253,6 +253,15 @@
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<mainClass>io.gravitee.policy.groovy.sandbox.GroovyWhitelistGenerator</mainClass>
<classpathScope>test</classpathScope>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -270,7 +268,7 @@ private boolean isMethodAllowed(Class<?> clazz, String methodName, Class<?>[] ar
return false;
}

Method method = MethodUtils.getMatchingAccessibleMethod(clazz, methodName, argumentClasses);
Method method = getMatchingAccessibleMethod(clazz, methodName, argumentClasses);

if (method != null && (isGroovyScriptDefinedMethod(method) || getAllowedMethods(clazz).contains(method))) {
// Allow method if directly defined in the script or if the method is explicitly allowed.
Expand All @@ -293,6 +291,25 @@ private boolean isMethodAllowed(Class<?> clazz, String methodName, Class<?>[] ar
return false;
}

private Method getMatchingAccessibleMethod(Class<?> clazz, String methodName, Class<?>[] argumentClasses) {
try {
return MethodUtils.getMatchingAccessibleMethod(clazz, methodName, argumentClasses);
} catch (InaccessibleObjectException e) {
Class<?> superclass = clazz.getSuperclass();
if (!superclass.equals(Object.class)) {
return getMatchingAccessibleMethod(superclass, methodName, argumentClasses);
}
Optional<Method> method = Arrays
.stream(clazz.getInterfaces())
.map(parent -> getMatchingAccessibleMethod(parent, methodName, argumentClasses))
.findFirst();
if (method.isPresent()) {
return method.get();
}
throw e;
}
}

private boolean isDGMAllowed(Class<?> clazz, String methodName, Class<?>[] argumentClasses) {
Class<?>[] selfArgs = new Class[argumentClasses.length + 1];
selfArgs[0] = clazz;
Expand All @@ -307,7 +324,7 @@ private boolean isDGMAllowed(Class<?> clazz, String methodName, Class<?>[] argum

// Try to find allowed method from default groovy methods.
for (Class<?> dgmClass : DGM_CLASSES) {
Method method = MethodUtils.getMatchingAccessibleMethod(dgmClass, methodName, selfArgs);
Method method = getMatchingAccessibleMethod(dgmClass, methodName, selfArgs);

if (method != null && getAllowedMethods(dgmClass).contains(method)) {
return true;
Expand Down Expand Up @@ -493,7 +510,7 @@ private static void parseDeclaration(
}
}

private static Method parseMethod(String declaration) throws Exception {
protected static Method parseMethod(String declaration) throws Exception {
String[] split = declaration.split(" ");
String clazzName = split[1];
String methodName = split[2];
Expand Down
Loading