Movatterモバイル変換


[0]ホーム

URL:


CodeQL documentation
CodeQL resources

Groovy Language injection

ID: java/groovy-injectionKind: path-problemSecurity severity: 9.3Severity: errorPrecision: highTags:   - security   - external/cwe/cwe-094Query suites:   - java-code-scanning.qls   - java-security-extended.qls   - java-security-and-quality.qls

Click to see the query in the CodeQL repository

Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. If a Groovy script is built using attacker-controlled data, and then evaluated, then it may allow the attacker to achieve RCE.

Recommendation

It is generally recommended to avoid using untrusted input in a Groovy evaluation. If this is not possible, use a sandbox solution. Developers must also take care that Groovy compile-time metaprogramming can also lead to RCE: it is possible to achieve RCE by compiling a Groovy script (see the article “Abusing Meta Programming for Unauthenticated RCE!” linked below). Groovy’sSecureASTCustomizer allows securing source code by controlling what code constructs are permitted. This is typically done when using Groovy for its scripting or domain specific language (DSL) features. The fundamental problem is that Groovy is a dynamic language, yetSecureASTCustomizer works by looking at Groovy AST statically. This makes it very easy for an attacker to bypass many of the intended checks (see [Groovy SecureASTCustomizer is harmful](https://kohsuke.org/2012/04/27/groovy-secureastcustomizer-is-harmful/)). Therefore, besidesSecureASTCustomizer, runtime checks are also necessary before calling Groovy methods (see [Improved sandboxing of Groovy scripts](https://melix.github.io/blog/2015/03/sandboxing.html)). It is also possible to use a block-list method, excluding unwanted classes from being loaded by the JVM. This method is not always recommended, because block-lists can be bypassed by unexpected values.

Example

The following example uses untrusted data to evaluate a Groovy script.

publicclassGroovyInjection{voidinjectionViaClassLoader(HttpServletRequestrequest){Stringscript=request.getParameter("script");finalGroovyClassLoaderclassLoader=newGroovyClassLoader();Classgroovy=classLoader.parseClass(script);// BAD: Groovy code injectionGroovyObjectgroovyObj=(GroovyObject)groovy.newInstance();}voidinjectionViaEval(HttpServletRequestrequest){Stringscript=request.getParameter("script");Eval.me(script);// BAD: Groovy code injection}voidinjectionViaGroovyShell(HttpServletRequestrequest){GroovyShellshell=newGroovyShell();Stringscript=request.getParameter("script");shell.evaluate(script);// BAD: Groovy code injection}voidinjectionViaGroovyShellGroovyCodeSource(HttpServletRequestrequest){GroovyShellshell=newGroovyShell();Stringscript=request.getParameter("script");GroovyCodeSourcegcs=newGroovyCodeSource(script,"test","Test");shell.evaluate(gcs);// BAD: Groovy code injection}}

The following example uses classloader block-list approach to exclude loading dangerous classes.

publicclassSandboxGroovyClassLoaderextendsClassLoader{publicSandboxGroovyClassLoader(ClassLoaderparent){super(parent);}/* override `loadClass` here to prevent loading sensitive classes, such as `java.lang.Runtime`, `java.lang.ProcessBuilder`, `java.lang.System`, etc.  *//* Note we must also block `groovy.transform.ASTTest`, `groovy.lang.GrabConfig` and `org.buildobjects.process.ProcBuilder` to prevent compile-time RCE. */staticvoidrunWithSandboxGroovyClassLoader()throwsException{// GOOD: route all class-loading via sand-boxing classloader.SandboxGroovyClassLoaderclassLoader=newGroovyClassLoader(newSandboxGroovyClassLoader());Class<?>scriptClass=classLoader.parseClass(untrusted.getQueryString());ObjectscriptInstance=scriptClass.newInstance();Objectresult=scriptClass.getDeclaredMethod("bar",newClass[]{}).invoke(scriptInstance,newObject[]{});}}

References


[8]ページ先頭

©2009-2025 Movatter.jp