PropertyConditionEvaluator implements ConditionEvaluator { protected Object getOGNLPropertyValue(Item item, String expression) throws Exception { if (expressionFilterFactory.getExpressionFilter("ognl").filter(expression) == null) { logger.warn("Expression {} is not allowed !", expression); return null; } OgnlContext ognlContext = getOgnlContext(secureFilteringClassLoader); ExpressionAccessor accessor = getPropertyAccessor(item, expression, ognlContext, secureFilteringClassLoader); return accessor != null ? accessor.get(ognlContext, item) : null; }  void setUsePropertyConditionOptimizations(boolean usePropertyConditionOptimizations); void setExpressionFilterFactory(ExpressionFilterFactory expressionFilterFactory); @Override boolean eval(Condition condition, Item item, Map<String, Object> context, ConditionEvaluatorDispatcher dispatcher); static final String NOT_OPTIMIZED_MARKER; }
@Test public void testOGNLSecurity() throws Exception { Event mockEvent = generateMockEvent(); File vulnFile = new File("target/vuln-file.txt"); if (vulnFile.exists()) { vulnFile.delete(); } String vulnFileCanonicalPath = vulnFile.getCanonicalPath(); vulnFileCanonicalPath = vulnFileCanonicalPath.replace("\\", "\\\\"); try { propertyConditionEvaluator.getOGNLPropertyValue(mockEvent, "@java.lang.Runtime@getRuntime().exec('touch " + vulnFileCanonicalPath + "')"); } catch (RuntimeException | MethodFailedException re) { } assertFalse("Vulnerability successfully executed ! File created at " + vulnFileCanonicalPath, vulnFile.exists()); try { propertyConditionEvaluator.getOGNLPropertyValue(mockEvent, "(#cmd='touch " + vulnFileCanonicalPath + "').(#cmds={'bash','-c',#cmd}).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start())"); } catch (RuntimeException | MethodFailedException re) { } vulnFile = new File("target/vuln-file.txt"); assertFalse("Vulnerability successfully executed ! File created at " + vulnFileCanonicalPath, vulnFile.exists()); try { propertyConditionEvaluator.getOGNLPropertyValue(mockEvent, "(#cmd='touch " + vulnFileCanonicalPath + "').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start())"); } catch (RuntimeException | MethodFailedException re) { } vulnFile = new File("target/vuln-file.txt"); assertFalse("Vulnerability successfully executed ! File created at " + vulnFileCanonicalPath, vulnFile.exists()); try { propertyConditionEvaluator.getOGNLPropertyValue(mockEvent, "(#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\")).(#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0]).(#rtobj = #getruntimemethod.invoke(null,null)).(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]).(#execmethod.invoke(#rtobj,\" touch "+vulnFileCanonicalPath+"\"))"); } catch (RuntimeException | MethodFailedException re) { } vulnFile = new File("target/vuln-file.txt"); assertFalse("Vulnerability successfully executed ! File created at " + vulnFileCanonicalPath, vulnFile.exists()); }