Movatterモバイル変換


[0]ホーム

URL:


CodeQL documentation
CodeQL resources

Expression language injection (JEXL)

ID: java/jexl-expression-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

Java EXpression Language (JEXL) is a simple expression language provided by the Apache Commons JEXL library. The syntax is close to a mix of ECMAScript and shell-script. The language allows invocation of methods available in the JVM. If a JEXL expression is built using attacker-controlled data, and then evaluated, then it may allow the attacker to run arbitrary code.

Recommendation

It is generally recommended to avoid using untrusted input in a JEXL expression. If it is not possible, JEXL expressions should be run in a sandbox that allows accessing only explicitly allowed classes.

Example

The following example uses untrusted data to build and run a JEXL expression.

publicvoidevaluate(Socketsocket)throwsIOException{try(BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream()))){Stringinput=reader.readLine();JexlEnginejexl=newJexlBuilder().create();// BAD: input is controlled by the userJexlExpressionexpression=jexl.createExpression(input);JexlContextcontext=newMapContext();expression.evaluate(context);}}

The next example shows how an untrusted JEXL expression can be run in a sandbox that allows accessing only methods in thejava.lang.Math class. The sandbox is implemented usingJexlSandbox class that is provided by Apache Commons JEXL 3.

publicvoidevaluate(Socketsocket)throwsIOException{try(BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream()))){JexlSandboxonlyMath=newJexlSandbox(false);onlyMath.white("java.lang.Math");JexlEnginejexl=newJexlBuilder().sandbox(onlyMath).create();// GOOD: using a sandboxStringinput=reader.readLine();JexlExpressionexpression=jexl.createExpression(input);JexlContextcontext=newMapContext();expression.evaluate(context);}}

The next example shows another way how a sandbox can be implemented. It uses a custom implementation ofJexlUberspect that checks if callees are instances of allowed classes.

publicvoidevaluate(Socketsocket)throwsIOException{try(BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream()))){JexlUberspectsandbox=newJexlUberspectSandbox();JexlEnginejexl=newJexlBuilder().uberspect(sandbox).create();Stringinput=reader.readLine();JexlExpressionexpression=jexl.createExpression(input);// GOOD: jexl uses a sandboxJexlContextcontext=newMapContext();expression.evaluate(context);}privatestaticclassJexlUberspectSandboximplementsJexlUberspect{privatestaticfinalList<String>ALLOWED_CLASSES=Arrays.asList("java.lang.Math","java.util.Random");privatefinalJexlUberspectuberspect=newJexlBuilder().create().getUberspect();privatevoidcheckAccess(Objectobj){if(!ALLOWED_CLASSES.contains(obj.getClass().getCanonicalName())){thrownewAccessControlException("Not allowed");}}@OverridepublicJexlMethodgetMethod(Objectobj,Stringmethod,Object...args){checkAccess(obj);returnuberspect.getMethod(obj,method,args);}@OverridepublicList<PropertyResolver>getResolvers(JexlOperatorop,Objectobj){checkAccess(obj);returnuberspect.getResolvers(op,obj);}@OverridepublicvoidsetClassLoader(ClassLoaderloader){uberspect.setClassLoader(loader);}@OverridepublicintgetVersion(){returnuberspect.getVersion();}@OverridepublicJexlMethodgetConstructor(Objectobj,Object...args){checkAccess(obj);returnuberspect.getConstructor(obj,args);}@OverridepublicJexlPropertyGetgetPropertyGet(Objectobj,Objectidentifier){checkAccess(obj);returnuberspect.getPropertyGet(obj,identifier);}@OverridepublicJexlPropertyGetgetPropertyGet(List<PropertyResolver>resolvers,Objectobj,Objectidentifier){checkAccess(obj);returnuberspect.getPropertyGet(resolvers,obj,identifier);}@OverridepublicJexlPropertySetgetPropertySet(Objectobj,Objectidentifier,Objectarg){checkAccess(obj);returnuberspect.getPropertySet(obj,identifier,arg);}@OverridepublicJexlPropertySetgetPropertySet(List<PropertyResolver>resolvers,Objectobj,Objectidentifier,Objectarg){checkAccess(obj);returnuberspect.getPropertySet(resolvers,obj,identifier,arg);}@OverridepublicIterator<?>getIterator(Objectobj){checkAccess(obj);returnuberspect.getIterator(obj);}@OverridepublicJexlArithmetic.UberspectgetArithmetic(JexlArithmeticarithmetic){returnuberspect.getArithmetic(arithmetic);}}}

References


[8]ページ先頭

©2009-2025 Movatter.jp