Skip to content

Instantly share code, notes, and snippets.

@artem-smotrakov
artem-smotrakov / RunExpressionJuel.java
Created April 14, 2021 07:41
Example of evaluating an expression with JUEL
public static Object evaluate(String expression) {
ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
ELContext context = new de.odysseus.el.util.SimpleContext();
ValueExpression e = factory.createValueExpression(context, expression, Object.class);
return e.getValue(context);
}
@artem-smotrakov
artem-smotrakov / ExpressionEvaluationSink.ql
Created April 14, 2021 07:10
Jakarta EL sinks for detecting EL injections with CodeQL, see also https://github.com/github/codeql/pull/5471
private class ExpressionEvaluationSink extends DataFlow::ExprNode {
ExpressionEvaluationSink() {
exists(MethodAccess ma, Method m, Expr taintFrom |
ma.getMethod() = m and taintFrom = this.asExpr()
|
m.getDeclaringType() instanceof ValueExpression and
m.hasName(["getValue", "setValue"]) and
ma.getQualifier() = taintFrom
or
m.getDeclaringType() instanceof MethodExpression and
@artem-smotrakov
artem-smotrakov / JakartaExpressionInjectionConfig.ql
Created April 14, 2021 07:05
CodeQL config for detecting Jakarta EL injections, see https://github.com/github/codeql/pull/5471 for details
class JakartaExpressionInjectionConfig extends TaintTracking::Configuration {
JakartaExpressionInjectionConfig() { this = "JakartaExpressionInjectionConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionEvaluationSink }
override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
any(TaintPropagatingCall c).taintFlow(fromNode, toNode) or
hasGetterFlow(fromNode, toNode)
@artem-smotrakov
artem-smotrakov / UnsafeSpringExporterInXMLConfiguration.ql
Last active March 25, 2021 12:45
A CodeQL query for detecting unsafe Spring service exporters in XML configurations
import java
import semmle.code.java.frameworks.spring.SpringBean
/**
* Holds if `type` is `RemoteInvocationSerializingExporter`.
*/
predicate isRemoteInvocationSerializingExporter(RefType type) {
type.getASupertype*()
.hasQualifiedName("org.springframework.remoting.rmi", "RemoteInvocationSerializingExporter")
}
@artem-smotrakov
artem-smotrakov / UnsafeSpringExporterInConfigurationClass.ql
Created March 25, 2021 12:43
A CodeQL query for detecting unsafe Spring exporters in String configuration
import java
import UnsafeSpringExporterLib
/**
* Holds if `type` is `RemoteInvocationSerializingExporter`.
*/
predicate isRemoteInvocationSerializingExporter(RefType type) {
type.getASupertype*()
.hasQualifiedName("org.springframework.remoting.rmi", "RemoteInvocationSerializingExporter")
}
@artem-smotrakov
artem-smotrakov / beans.xml
Created March 25, 2021 12:22
An example of a vulnerable HTTP endpoint based on HttpInvokerServiceExporter (CVE-2016-1000027)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="accountService" class="com.gypsyengineer.server.AccountServiceImpl"/>
<bean name="/account" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
@artem-smotrakov
artem-smotrakov / UnsafeHttpInvokerServiceExporter.java
Created March 25, 2021 12:19
An example of a vulnerable HTTP endpoint based on HttpInvokerServiceExporter (CVE-2016-1000027)
@Configuration
class Server {
@Bean(name = "/account")
HttpInvokerServiceExporter accountService() {
HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
exporter.setService(new AccountServiceImpl());
exporter.setServiceInterface(AccountService.class);
return exporter;
}
@artem-smotrakov
artem-smotrakov / JexlEvaluationSink.ql
Created February 17, 2021 13:40
JEXL sinks for detecting JEXL injections with CodeQL
private class JexlEvaluationSink extends DataFlow::ExprNode {
JexlEvaluationSink() {
exists(MethodAccess ma, Method m, Expr taintFrom |
ma.getMethod() = m and taintFrom = this.asExpr()
|
m instanceof DirectJexlEvaluationMethod and ma.getQualifier() = taintFrom
or
m instanceof CreateJexlCallableMethod and ma.getQualifier() = taintFrom
or
m instanceof JexlEngineGetSetPropertyMethod and
@artem-smotrakov
artem-smotrakov / JexlInjectionConfig.ql
Last active February 17, 2021 13:27
CodeQL config for detecting JEXL injections, see https://github.com/github/codeql/pull/4965/files for details
class JexlInjectionConfig extends TaintTracking::Configuration {
JexlInjectionConfig() { this = "JexlInjectionConfig" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink }
override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
@artem-smotrakov
artem-smotrakov / SandboxedJEXL.java
Last active February 17, 2021 12:36
Run JEXL expressions in a sandbox implemented with JexlUberspect
void runJexl(String jexlExpr) {
JexlUberspect sandbox = new JexlUberspectSandbox();
JexlEngine jexl = new JexlBuilder().uberspect(sandbox).create();
JexlExpression expression = jexl.createExpression(jexlExpr);
JexlContext context = new MapContext();
expression.evaluate(context);
}
private static class JexlUberspectSandbox implements JexlUberspect {