Hi, guys!
I'm developing plugin for Elasticsearch 2.3 which does simple conversion of found documents for search client. This plugin uses Groovy scripts which does this conversion. I'm faced with curious problem: for example, when this script is evaluated by Elasticsearch's script service:
if (doc.field instanceof Double) {
// do some conversion under field
}
Here is ok, script works fine, but this:
// changed Double to Number to cover all types of numbers
if (doc.field instanceof Number) {
// do some conversion under field
}
gives strange exception in logs:
ScriptException[failed to compile groovy script]; nested: MultipleCompilationErrorsException[startup failed:
fd3511425ed9b373349aefab43c955d014d045e4: 1: unable to resolve class Number
So, I dug deeper and found that real exception is SecurityException
wrapped into ClassNotFoundException
, which is done in GroovyScriptEngineService
:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (sm != null) {
try {
engineContext.checkPermission(new ClassPermission(name));
} catch (SecurityException e) {
throw new ClassNotFoundException(name, e);
}
}
return super.loadClass(name, resolve);
}
but nothing of them has been logged.
Then I found a place in class org.elasticsearch.script.ClassPermission
where the list of permitted classes is created:
// this is the list from the old grovy sandbox impl (+ some things like String, Iterator, etc that were missing)
public static final Set<String> STANDARD_CLASSES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
// jdk classes
java.lang.Boolean.class.getName(),
java.lang.Byte.class.getName(),
java.lang.Character.class.getName(),
java.lang.Double.class.getName(),
...
and there is no java.lang.Number
, but mentioned java.lang.Double
is added.
Questions of this topic:
- Why I had to do non-trivial actions to know that I have to just grant access to some "forbidden" class in policy file ?
- How do you think, is it normal to make grant to
java.lang.Number
in policy file, and other classes fromjava.lang
not enumerated inSTANDARD_CLASSES
?