mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
Merge pull request #5931 from atorralba/atorralba/promote-jndi-injection
Java: Promote JNDI Injection query from experimental
This commit is contained in:
2
java/change-notes/2021-05-20-jndi-injection-query.md
Normal file
2
java/change-notes/2021-05-20-jndi-injection-query.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
lgtm,codescanning
|
||||||
|
* The query "JNDI lookup with user-controlled name" (`java/jndi-injection`) has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @ggolawski](https://github.com/github/codeql/pull/3288).
|
||||||
@@ -11,7 +11,7 @@ code execution.</p>
|
|||||||
</overview>
|
</overview>
|
||||||
|
|
||||||
<recommendation>
|
<recommendation>
|
||||||
<p>The general recommendation is to not pass untrusted data to the <code>InitialContext.lookup
|
<p>The general recommendation is to avoid passing untrusted data to the <code>InitialContext.lookup
|
||||||
</code> method. If the name being used to look up the object must be provided by the user, make
|
</code> method. If the name being used to look up the object must be provided by the user, make
|
||||||
sure that it's not in the form of an absolute URL or that it's the URL pointing to a trused server.
|
sure that it's not in the form of an absolute URL or that it's the URL pointing to a trused server.
|
||||||
</p>
|
</p>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @name JNDI lookup with user-controlled name
|
* @name JNDI lookup with user-controlled name
|
||||||
* @description Doing a JNDI lookup with user-controlled name can lead to download an untrusted
|
* @description Performing a JNDI lookup with a user-controlled name can lead to the download of an untrusted
|
||||||
* object and to execution of arbitrary code.
|
* object and to execution of arbitrary code.
|
||||||
* @kind path-problem
|
* @kind path-problem
|
||||||
* @problem.severity error
|
* @problem.severity error
|
||||||
@@ -11,8 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java
|
import java
|
||||||
import semmle.code.java.dataflow.FlowSources
|
import semmle.code.java.security.JndiInjectionQuery
|
||||||
import JndiInjectionLib
|
|
||||||
import DataFlow::PathGraph
|
import DataFlow::PathGraph
|
||||||
|
|
||||||
from DataFlow::PathNode source, DataFlow::PathNode sink, JndiInjectionFlowConfig conf
|
from DataFlow::PathNode source, DataFlow::PathNode sink, JndiInjectionFlowConfig conf
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
import java
|
|
||||||
import semmle.code.java.dataflow.FlowSources
|
|
||||||
import DataFlow
|
|
||||||
import experimental.semmle.code.java.frameworks.Jndi
|
|
||||||
import experimental.semmle.code.java.frameworks.spring.SpringJndi
|
|
||||||
import semmle.code.java.frameworks.SpringLdap
|
|
||||||
import experimental.semmle.code.java.frameworks.Shiro
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A taint-tracking configuration for unvalidated user input that is used in JNDI lookup.
|
|
||||||
*/
|
|
||||||
class JndiInjectionFlowConfig extends TaintTracking::Configuration {
|
|
||||||
JndiInjectionFlowConfig() { this = "JndiInjectionFlowConfig" }
|
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
|
||||||
|
|
||||||
override predicate isSink(DataFlow::Node sink) { sink instanceof JndiInjectionSink }
|
|
||||||
|
|
||||||
override predicate isSanitizer(DataFlow::Node node) {
|
|
||||||
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
||||||
nameStep(node1, node2) or
|
|
||||||
jmxServiceUrlStep(node1, node2) or
|
|
||||||
jmxConnectorStep(node1, node2) or
|
|
||||||
rmiConnectorStep(node1, node2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `java.util.Hashtable`. */
|
|
||||||
class TypeHashtable extends Class {
|
|
||||||
TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `javax.naming.directory.SearchControls`. */
|
|
||||||
class TypeSearchControls extends Class {
|
|
||||||
TypeSearchControls() { this.hasQualifiedName("javax.naming.directory", "SearchControls") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The interface `org.springframework.ldap.core.LdapOperations` (spring-ldap 1.2.x and newer) or
|
|
||||||
* `org.springframework.ldap.LdapOperations` (spring-ldap 1.1.x).
|
|
||||||
*/
|
|
||||||
class TypeSpringLdapOperations extends Interface {
|
|
||||||
TypeSpringLdapOperations() {
|
|
||||||
this.hasQualifiedName("org.springframework.ldap.core", "LdapOperations") or
|
|
||||||
this.hasQualifiedName("org.springframework.ldap", "LdapOperations")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The interface `org.springframework.ldap.core.ContextMapper` (spring-ldap 1.2.x and newer) or
|
|
||||||
* `org.springframework.ldap.ContextMapper` (spring-ldap 1.1.x).
|
|
||||||
*/
|
|
||||||
class TypeSpringContextMapper extends Interface {
|
|
||||||
TypeSpringContextMapper() {
|
|
||||||
this.getSourceDeclaration().hasQualifiedName("org.springframework.ldap.core", "ContextMapper") or
|
|
||||||
this.getSourceDeclaration().hasQualifiedName("org.springframework.ldap", "ContextMapper")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The interface `javax.management.remote.JMXConnector`. */
|
|
||||||
class TypeJMXConnector extends Interface {
|
|
||||||
TypeJMXConnector() { this.hasQualifiedName("javax.management.remote", "JMXConnector") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `javax.management.remote.rmi.RMIConnector`. */
|
|
||||||
class TypeRMIConnector extends Class {
|
|
||||||
TypeRMIConnector() { this.hasQualifiedName("javax.management.remote.rmi", "RMIConnector") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `javax.management.remote.JMXConnectorFactory`. */
|
|
||||||
class TypeJMXConnectorFactory extends Class {
|
|
||||||
TypeJMXConnectorFactory() {
|
|
||||||
this.hasQualifiedName("javax.management.remote", "JMXConnectorFactory")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `javax.management.remote.JMXServiceURL`. */
|
|
||||||
class TypeJMXServiceURL extends Class {
|
|
||||||
TypeJMXServiceURL() { this.hasQualifiedName("javax.management.remote", "JMXServiceURL") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The interface `javax.naming.Context`. */
|
|
||||||
class TypeNamingContext extends Interface {
|
|
||||||
TypeNamingContext() { this.hasQualifiedName("javax.naming", "Context") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JNDI sink for JNDI injection vulnerabilities, i.e. 1st argument to `lookup`, `lookupLink`,
|
|
||||||
* `doLookup`, `rename`, `list` or `listBindings` method from `InitialContext`.
|
|
||||||
*/
|
|
||||||
predicate jndiSinkMethod(Method m, int index) {
|
|
||||||
m.getDeclaringType().getAnAncestor() instanceof TypeInitialContext and
|
|
||||||
(
|
|
||||||
m.hasName("lookup") or
|
|
||||||
m.hasName("lookupLink") or
|
|
||||||
m.hasName("doLookup") or
|
|
||||||
m.hasName("rename") or
|
|
||||||
m.hasName("list") or
|
|
||||||
m.hasName("listBindings")
|
|
||||||
) and
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring sink for JNDI injection vulnerabilities, i.e. 1st argument to `lookup` method from
|
|
||||||
* Spring's `JndiTemplate`.
|
|
||||||
*/
|
|
||||||
predicate springJndiTemplateSinkMethod(Method m, int index) {
|
|
||||||
m.getDeclaringType() instanceof TypeSpringJndiTemplate and
|
|
||||||
m.hasName("lookup") and
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring sink for JNDI injection vulnerabilities, i.e. 1st argument to `lookup`, `lookupContext`,
|
|
||||||
* `findByDn`, `rename`, `list`, `listBindings`, `unbind`, `search` or `searchForObject` method
|
|
||||||
* from Spring's `LdapOperations`.
|
|
||||||
*/
|
|
||||||
predicate springLdapTemplateSinkMethod(MethodAccess ma, Method m, int index) {
|
|
||||||
m.getDeclaringType().getAnAncestor() instanceof TypeSpringLdapOperations and
|
|
||||||
(
|
|
||||||
m.hasName("lookup")
|
|
||||||
or
|
|
||||||
m.hasName("lookupContext")
|
|
||||||
or
|
|
||||||
m.hasName("findByDn")
|
|
||||||
or
|
|
||||||
m.hasName("rename")
|
|
||||||
or
|
|
||||||
m.hasName("list")
|
|
||||||
or
|
|
||||||
m.hasName("listBindings")
|
|
||||||
or
|
|
||||||
m.hasName("unbind") and ma.getArgument(1).(CompileTimeConstantExpr).getBooleanValue() = true
|
|
||||||
or
|
|
||||||
m.getName().matches("search%") and
|
|
||||||
m.getParameterType(m.getNumberOfParameters() - 1) instanceof TypeSpringContextMapper and
|
|
||||||
not m.getAParamType() instanceof TypeSearchControls
|
|
||||||
or
|
|
||||||
m.hasName("search") and ma.getArgument(3).(CompileTimeConstantExpr).getBooleanValue() = true
|
|
||||||
) and
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apache Shiro sink for JNDI injection vulnerabilities, i.e. 1st argument to `lookup` method from
|
|
||||||
* Shiro's `JndiTemplate`.
|
|
||||||
*/
|
|
||||||
predicate shiroSinkMethod(Method m, int index) {
|
|
||||||
m.getDeclaringType() instanceof TypeShiroJndiTemplate and
|
|
||||||
m.hasName("lookup") and
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `JMXConnectorFactory` sink for JNDI injection vulnerabilities, i.e. 1st argument to `connect`
|
|
||||||
* method from `JMXConnectorFactory`.
|
|
||||||
*/
|
|
||||||
predicate jmxConnectorFactorySinkMethod(Method m, int index) {
|
|
||||||
m.getDeclaringType() instanceof TypeJMXConnectorFactory and
|
|
||||||
m.hasName("connect") and
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tainted value passed to env `Hashtable` as the provider URL, i.e.
|
|
||||||
* `env.put(Context.PROVIDER_URL, tainted)` or `env.setProperty(Context.PROVIDER_URL, tainted)`.
|
|
||||||
*/
|
|
||||||
predicate providerUrlEnv(MethodAccess ma, Method m, int index) {
|
|
||||||
m.getDeclaringType().getAnAncestor() instanceof TypeHashtable and
|
|
||||||
(m.hasName("put") or m.hasName("setProperty")) and
|
|
||||||
(
|
|
||||||
ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "java.naming.provider.url"
|
|
||||||
or
|
|
||||||
exists(Field f |
|
|
||||||
ma.getArgument(0) = f.getAnAccess() and
|
|
||||||
f.hasName("PROVIDER_URL") and
|
|
||||||
f.getDeclaringType() instanceof TypeNamingContext
|
|
||||||
)
|
|
||||||
) and
|
|
||||||
index = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if parameter at index `index` in method `m` is JNDI injection sink. */
|
|
||||||
predicate jndiInjectionSinkMethod(MethodAccess ma, Method m, int index) {
|
|
||||||
jndiSinkMethod(m, index) or
|
|
||||||
springJndiTemplateSinkMethod(m, index) or
|
|
||||||
springLdapTemplateSinkMethod(ma, m, index) or
|
|
||||||
shiroSinkMethod(m, index) or
|
|
||||||
jmxConnectorFactorySinkMethod(m, index) or
|
|
||||||
providerUrlEnv(ma, m, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A data flow sink for unvalidated user input that is used in JNDI lookup. */
|
|
||||||
class JndiInjectionSink extends DataFlow::ExprNode {
|
|
||||||
JndiInjectionSink() {
|
|
||||||
exists(MethodAccess ma, Method m, int index |
|
|
||||||
ma.getMethod() = m and
|
|
||||||
ma.getArgument(index) = this.getExpr() and
|
|
||||||
jndiInjectionSinkMethod(ma, m, index)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(MethodAccess ma, Method m |
|
|
||||||
ma.getMethod() = m and
|
|
||||||
ma.getQualifier() = this.getExpr() and
|
|
||||||
m.getDeclaringType().getAnAncestor() instanceof TypeJMXConnector and
|
|
||||||
m.hasName("connect")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `CompositeName` or
|
|
||||||
* `CompoundName`, i.e. `new CompositeName(tainted)` or `new CompoundName(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate nameStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(ConstructorCall cc |
|
|
||||||
cc.getConstructedType() instanceof TypeCompositeName or
|
|
||||||
cc.getConstructedType() instanceof TypeCompoundName
|
|
||||||
|
|
|
||||||
n1.asExpr() = cc.getAnArgument() and
|
|
||||||
n2.asExpr() = cc
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `JMXServiceURL`,
|
|
||||||
* i.e. `new JMXServiceURL(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate jmxServiceUrlStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeJMXServiceURL |
|
|
||||||
n1.asExpr() = cc.getAnArgument() and
|
|
||||||
n2.asExpr() = cc
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `JMXServiceURL` and
|
|
||||||
* `JMXConnector`, i.e. `JMXConnectorFactory.newJMXConnector(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate jmxConnectorStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getArgument(0) and n2.asExpr() = ma |
|
|
||||||
ma.getMethod() = m and
|
|
||||||
m.getDeclaringType() instanceof TypeJMXConnectorFactory and
|
|
||||||
m.hasName("newJMXConnector")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `JMXServiceURL` and
|
|
||||||
* `RMIConnector`, i.e. `new RMIConnector(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate rmiConnectorStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeRMIConnector |
|
|
||||||
n1.asExpr() = cc.getAnArgument() and
|
|
||||||
n2.asExpr() = cc
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -30,11 +30,6 @@ class InsecureLdapUrlLiteral extends StringLiteral {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The interface `javax.naming.Context`. */
|
|
||||||
class TypeNamingContext extends Interface {
|
|
||||||
TypeNamingContext() { this.hasQualifiedName("javax.naming", "Context") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `java.util.Hashtable`. */
|
/** The class `java.util.Hashtable`. */
|
||||||
class TypeHashtable extends Class {
|
class TypeHashtable extends Class {
|
||||||
TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") }
|
TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") }
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
import java
|
|
||||||
|
|
||||||
/** The class `javax.naming.InitialContext`. */
|
|
||||||
class TypeInitialContext extends Class {
|
|
||||||
TypeInitialContext() { this.hasQualifiedName("javax.naming", "InitialContext") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `javax.naming.CompositeName`. */
|
|
||||||
class TypeCompositeName extends Class {
|
|
||||||
TypeCompositeName() { this.hasQualifiedName("javax.naming", "CompositeName") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `javax.naming.CompoundName`. */
|
|
||||||
class TypeCompoundName extends Class {
|
|
||||||
TypeCompoundName() { this.hasQualifiedName("javax.naming", "CompoundName") }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import java
|
|
||||||
|
|
||||||
/** The class `org.apache.shiro.jndi.JndiTemplate`. */
|
|
||||||
class TypeShiroJndiTemplate extends Class {
|
|
||||||
TypeShiroJndiTemplate() { this.hasQualifiedName("org.apache.shiro.jndi", "JndiTemplate") }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import java
|
|
||||||
|
|
||||||
/** The class `org.springframework.jndi.JndiTemplate`. */
|
|
||||||
class TypeSpringJndiTemplate extends Class {
|
|
||||||
TypeSpringJndiTemplate() { this.hasQualifiedName("org.springframework.jndi", "JndiTemplate") }
|
|
||||||
}
|
|
||||||
@@ -86,3 +86,20 @@ class JMXRegistrationMethod extends Method {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The class `javax.management.remote.JMXConnectorFactory`. */
|
||||||
|
class TypeJMXConnectorFactory extends Class {
|
||||||
|
TypeJMXConnectorFactory() {
|
||||||
|
this.hasQualifiedName("javax.management.remote", "JMXConnectorFactory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `javax.management.remote.JMXServiceURL`. */
|
||||||
|
class TypeJMXServiceURL extends Class {
|
||||||
|
TypeJMXServiceURL() { this.hasQualifiedName("javax.management.remote", "JMXServiceURL") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `javax.management.remote.rmi.RMIConnector`. */
|
||||||
|
class TypeRMIConnector extends Class {
|
||||||
|
TypeRMIConnector() { this.hasQualifiedName("javax.management.remote.rmi", "RMIConnector") }
|
||||||
|
}
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ private module Frameworks {
|
|||||||
private import semmle.code.java.security.InformationLeak
|
private import semmle.code.java.security.InformationLeak
|
||||||
private import semmle.code.java.security.GroovyInjection
|
private import semmle.code.java.security.GroovyInjection
|
||||||
private import semmle.code.java.security.JexlInjectionSinkModels
|
private import semmle.code.java.security.JexlInjectionSinkModels
|
||||||
|
private import semmle.code.java.security.JndiInjection
|
||||||
private import semmle.code.java.security.LdapInjection
|
private import semmle.code.java.security.LdapInjection
|
||||||
private import semmle.code.java.security.MvelInjection
|
private import semmle.code.java.security.MvelInjection
|
||||||
private import semmle.code.java.security.OgnlInjection
|
private import semmle.code.java.security.OgnlInjection
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Provides classes and predicates for working with the Java JDBC API.
|
* Provides classes and predicates for working with the Java JNDI API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java
|
import java
|
||||||
@@ -7,11 +7,31 @@ import semmle.code.java.Type
|
|||||||
import semmle.code.java.Member
|
import semmle.code.java.Member
|
||||||
|
|
||||||
/*--- Types ---*/
|
/*--- Types ---*/
|
||||||
|
/** The interface `javax.naming.Context`. */
|
||||||
|
class TypeNamingContext extends Interface {
|
||||||
|
TypeNamingContext() { this.hasQualifiedName("javax.naming", "Context") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `javax.naming.CompositeName`. */
|
||||||
|
class TypeCompositeName extends Class {
|
||||||
|
TypeCompositeName() { this.hasQualifiedName("javax.naming", "CompositeName") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `javax.naming.CompoundName`. */
|
||||||
|
class TypeCompoundName extends Class {
|
||||||
|
TypeCompoundName() { this.hasQualifiedName("javax.naming", "CompoundName") }
|
||||||
|
}
|
||||||
|
|
||||||
/** The interface `javax.naming.directory.DirContext`. */
|
/** The interface `javax.naming.directory.DirContext`. */
|
||||||
class TypeDirContext extends Interface {
|
class TypeDirContext extends Interface {
|
||||||
TypeDirContext() { this.hasQualifiedName("javax.naming.directory", "DirContext") }
|
TypeDirContext() { this.hasQualifiedName("javax.naming.directory", "DirContext") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The class `javax.naming.directory.SearchControls` */
|
||||||
|
class TypeSearchControls extends Class {
|
||||||
|
TypeSearchControls() { this.hasQualifiedName("javax.naming.directory", "SearchControls") }
|
||||||
|
}
|
||||||
|
|
||||||
/** The class `javax.naming.ldap.LdapName`. */
|
/** The class `javax.naming.ldap.LdapName`. */
|
||||||
class TypeLdapName extends Class {
|
class TypeLdapName extends Class {
|
||||||
TypeLdapName() { this.hasQualifiedName("javax.naming.ldap", "LdapName") }
|
TypeLdapName() { this.hasQualifiedName("javax.naming.ldap", "LdapName") }
|
||||||
|
|||||||
@@ -59,6 +59,17 @@ class TypeSpringLdapUtils extends Class {
|
|||||||
TypeSpringLdapUtils() { this.hasQualifiedName("org.springframework.ldap.support", "LdapUtils") }
|
TypeSpringLdapUtils() { this.hasQualifiedName("org.springframework.ldap.support", "LdapUtils") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface `org.springframework.ldap.core.LdapOperations` or
|
||||||
|
* `org.springframework.ldap.LdapOperations`
|
||||||
|
*/
|
||||||
|
class TypeLdapOperations extends Interface {
|
||||||
|
TypeLdapOperations() {
|
||||||
|
this.hasQualifiedName(["org.springframework.ldap.core", "org.springframework.ldap"],
|
||||||
|
"LdapOperations")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*--- Methods ---*/
|
/*--- Methods ---*/
|
||||||
/**
|
/**
|
||||||
* A method with the name `authenticate` declared in
|
* A method with the name `authenticate` declared in
|
||||||
|
|||||||
206
java/ql/src/semmle/code/java/security/JndiInjection.qll
Normal file
206
java/ql/src/semmle/code/java/security/JndiInjection.qll
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
/** Provides classes to reason about JNDI injection vulnerabilities. */
|
||||||
|
|
||||||
|
import java
|
||||||
|
private import semmle.code.java.dataflow.DataFlow
|
||||||
|
private import semmle.code.java.dataflow.ExternalFlow
|
||||||
|
private import semmle.code.java.frameworks.Jndi
|
||||||
|
private import semmle.code.java.frameworks.SpringLdap
|
||||||
|
|
||||||
|
/** A data flow sink for unvalidated user input that is used in JNDI lookup. */
|
||||||
|
abstract class JndiInjectionSink extends DataFlow::Node { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A unit class for adding additional taint steps.
|
||||||
|
*
|
||||||
|
* Extend this class to add additional taint steps that should apply to
|
||||||
|
* the `JndiInjectionFlowConfig` configuration.
|
||||||
|
*/
|
||||||
|
class JndiInjectionAdditionalTaintStep extends Unit {
|
||||||
|
/**
|
||||||
|
* Holds if the step from `node1` to `node2` should be considered a taint
|
||||||
|
* step for the `JndiInjectionFlowConfig` configuration.
|
||||||
|
*/
|
||||||
|
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A default sink representing methods susceptible to JNDI injection attacks. */
|
||||||
|
private class DefaultJndiInjectionSink extends JndiInjectionSink {
|
||||||
|
DefaultJndiInjectionSink() { sinkNode(this, "jndi-injection") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A method that does a JNDI lookup when it receives a specific argument set to `true`.
|
||||||
|
*/
|
||||||
|
private class ConditionedJndiInjectionSink extends JndiInjectionSink, DataFlow::ExprNode {
|
||||||
|
ConditionedJndiInjectionSink() {
|
||||||
|
exists(MethodAccess ma, Method m |
|
||||||
|
ma.getMethod() = m and
|
||||||
|
ma.getArgument(0) = this.asExpr() and
|
||||||
|
m.getDeclaringType().getASourceSupertype*() instanceof TypeLdapOperations
|
||||||
|
|
|
||||||
|
m.hasName("search") and
|
||||||
|
ma.getArgument(3).(CompileTimeConstantExpr).getBooleanValue() = true
|
||||||
|
or
|
||||||
|
m.hasName("unbind") and
|
||||||
|
ma.getArgument(1).(CompileTimeConstantExpr).getBooleanValue() = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tainted value passed to env `Hashtable` as the provider URL by calling
|
||||||
|
* `env.put(Context.PROVIDER_URL, tainted)` or `env.setProperty(Context.PROVIDER_URL, tainted)`.
|
||||||
|
*/
|
||||||
|
private class ProviderUrlJndiInjectionSink extends JndiInjectionSink, DataFlow::ExprNode {
|
||||||
|
ProviderUrlJndiInjectionSink() {
|
||||||
|
exists(MethodAccess ma, Method m |
|
||||||
|
ma.getMethod() = m and
|
||||||
|
ma.getArgument(1) = this.getExpr()
|
||||||
|
|
|
||||||
|
m.getDeclaringType().getASourceSupertype*() instanceof TypeHashtable and
|
||||||
|
(m.hasName("put") or m.hasName("setProperty")) and
|
||||||
|
(
|
||||||
|
ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "java.naming.provider.url"
|
||||||
|
or
|
||||||
|
exists(Field f |
|
||||||
|
ma.getArgument(0) = f.getAnAccess() and
|
||||||
|
f.hasName("PROVIDER_URL") and
|
||||||
|
f.getDeclaringType() instanceof TypeNamingContext
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** CSV sink models representing methods susceptible to JNDI injection attacks. */
|
||||||
|
private class DefaultJndiInjectionSinkModel extends SinkModelCsv {
|
||||||
|
override predicate row(string row) {
|
||||||
|
row =
|
||||||
|
[
|
||||||
|
"javax.naming;Context;true;lookup;;;Argument[0];jndi-injection",
|
||||||
|
"javax.naming;Context;true;lookupLink;;;Argument[0];jndi-injection",
|
||||||
|
"javax.naming;Context;true;rename;;;Argument[0];jndi-injection",
|
||||||
|
"javax.naming;Context;true;list;;;Argument[0];jndi-injection",
|
||||||
|
"javax.naming;Context;true;listBindings;;;Argument[0];jndi-injection",
|
||||||
|
"javax.naming;InitialContext;true;doLookup;;;Argument[0];jndi-injection",
|
||||||
|
"javax.management.remote;JMXConnector;true;connect;;;Argument[-1];jndi-injection",
|
||||||
|
"javax.management.remote;JMXConnectorFactory;false;connect;;;Argument[0];jndi-injection",
|
||||||
|
// Spring
|
||||||
|
"org.springframework.jndi;JndiTemplate;false;lookup;;;Argument[0];jndi-injection",
|
||||||
|
// spring-ldap 1.2.x and newer
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;lookup;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;lookupContext;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;findByDn;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;rename;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;list;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;listBindings;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;search;(Name,String,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;search;(Name,String,int,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;search;(Name,String,int,String[],ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;search;(String,String,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;search;(String,String,int,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;search;(String,String,int,String[],ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;searchForObject;(Name,String,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap.core;LdapOperations;true;searchForObject;(String,String,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
// spring-ldap 1.1.x
|
||||||
|
"org.springframework.ldap;LdapOperations;true;lookup;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;lookupContext;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;findByDn;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;rename;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;list;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;listBindings;;;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;search;(Name,String,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;search;(Name,String,int,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;search;(Name,String,int,String[],ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;search;(String,String,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;search;(String,String,int,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;search;(String,String,int,String[],ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;searchForObject;(Name,String,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
"org.springframework.ldap;LdapOperations;true;searchForObject;(String,String,ContextMapper);;Argument[0];jndi-injection",
|
||||||
|
// Shiro
|
||||||
|
"org.apache.shiro.jndi;JndiTemplate;false;lookup;;;Argument[0];jndi-injection"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A set of additional taint steps to consider when taint tracking JNDI injection related data flows. */
|
||||||
|
private class DefaultJndiInjectionAdditionalTaintStep extends JndiInjectionAdditionalTaintStep {
|
||||||
|
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
|
nameStep(node1, node2) or
|
||||||
|
nameAddStep(node1, node2) or
|
||||||
|
jmxServiceUrlStep(node1, node2) or
|
||||||
|
jmxConnectorStep(node1, node2) or
|
||||||
|
rmiConnectorStep(node1, node2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `CompositeName` or
|
||||||
|
* `CompoundName` by calling `new CompositeName(tainted)` or `new CompoundName(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate nameStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
|
||||||
|
exists(ConstructorCall cc |
|
||||||
|
cc.getConstructedType() instanceof TypeCompositeName or
|
||||||
|
cc.getConstructedType() instanceof TypeCompoundName
|
||||||
|
|
|
||||||
|
n1.asExpr() = cc.getAnArgument() and
|
||||||
|
n2.asExpr() = cc
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `CompositeName` or
|
||||||
|
* `CompoundName` by calling `new CompositeName().add(tainted)` or `new CompoundName().add(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate nameAddStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
|
||||||
|
exists(Method m, MethodAccess ma |
|
||||||
|
ma.getMethod() = m and
|
||||||
|
m.hasName("add") and
|
||||||
|
(
|
||||||
|
m.getDeclaringType() instanceof TypeCompositeName or
|
||||||
|
m.getDeclaringType() instanceof TypeCompoundName
|
||||||
|
)
|
||||||
|
|
|
||||||
|
n1.asExpr() = ma.getAnArgument() and
|
||||||
|
n2.asExpr() = ma
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `JMXServiceURL`
|
||||||
|
* by calling `new JMXServiceURL(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate jmxServiceUrlStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
|
||||||
|
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeJMXServiceURL |
|
||||||
|
n1.asExpr() = cc.getAnArgument() and
|
||||||
|
n2.asExpr() = cc
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `JMXServiceURL` and
|
||||||
|
* `JMXConnector` by calling `JMXConnectorFactory.newJMXConnector(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate jmxConnectorStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
|
||||||
|
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getArgument(0) and n2.asExpr() = ma |
|
||||||
|
ma.getMethod() = m and
|
||||||
|
m.getDeclaringType() instanceof TypeJMXConnectorFactory and
|
||||||
|
m.hasName("newJMXConnector")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `JMXServiceURL` and
|
||||||
|
* `RMIConnector` by calling `new RMIConnector(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate rmiConnectorStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
|
||||||
|
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeRMIConnector |
|
||||||
|
n1.asExpr() = cc.getAnArgument() and
|
||||||
|
n2.asExpr() = cc
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `java.util.Hashtable`. */
|
||||||
|
private class TypeHashtable extends Class {
|
||||||
|
TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") }
|
||||||
|
}
|
||||||
97
java/ql/src/semmle/code/java/security/JndiInjectionQuery.qll
Normal file
97
java/ql/src/semmle/code/java/security/JndiInjectionQuery.qll
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/** Provides taint tracking configurations to be used in JNDI injection queries. */
|
||||||
|
|
||||||
|
import java
|
||||||
|
import semmle.code.java.dataflow.FlowSources
|
||||||
|
import semmle.code.java.frameworks.Jndi
|
||||||
|
import semmle.code.java.frameworks.SpringLdap
|
||||||
|
import semmle.code.java.security.JndiInjection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A taint-tracking configuration for unvalidated user input that is used in JNDI lookup.
|
||||||
|
*/
|
||||||
|
class JndiInjectionFlowConfig extends TaintTracking::Configuration {
|
||||||
|
JndiInjectionFlowConfig() { this = "JndiInjectionFlowConfig" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) { sink instanceof JndiInjectionSink }
|
||||||
|
|
||||||
|
override predicate isSanitizer(DataFlow::Node node) {
|
||||||
|
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
|
any(JndiInjectionAdditionalTaintStep c).step(node1, node2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A method that does a JNDI lookup when it receives a `SearchControls` argument with `setReturningObjFlag` = `true`
|
||||||
|
*/
|
||||||
|
private class UnsafeSearchControlsSink extends JndiInjectionSink {
|
||||||
|
UnsafeSearchControlsSink() {
|
||||||
|
exists(UnsafeSearchControlsConf conf, MethodAccess ma |
|
||||||
|
conf.hasFlowTo(DataFlow::exprNode(ma.getAnArgument()))
|
||||||
|
|
|
||||||
|
this.asExpr() = ma.getArgument(0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find flows between a `SearchControls` object with `setReturningObjFlag` = `true`
|
||||||
|
* and an argument of an `LdapOperations.search` or `DirContext.search` call.
|
||||||
|
*/
|
||||||
|
private class UnsafeSearchControlsConf extends DataFlow2::Configuration {
|
||||||
|
UnsafeSearchControlsConf() { this = "UnsafeSearchControlsConf" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node source) { source instanceof UnsafeSearchControls }
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeSearchControlsArgument }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An argument of type `SearchControls` of an `LdapOperations.search` or `DirContext.search` call.
|
||||||
|
*/
|
||||||
|
private class UnsafeSearchControlsArgument extends DataFlow::ExprNode {
|
||||||
|
UnsafeSearchControlsArgument() {
|
||||||
|
exists(MethodAccess ma, Method m |
|
||||||
|
ma.getMethod() = m and
|
||||||
|
ma.getAnArgument() = this.asExpr() and
|
||||||
|
this.asExpr().getType() instanceof TypeSearchControls and
|
||||||
|
m.hasName("search")
|
||||||
|
|
|
||||||
|
m.getDeclaringType().getASourceSupertype*() instanceof TypeLdapOperations or
|
||||||
|
m.getDeclaringType().getASourceSupertype*() instanceof TypeDirContext
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `SearchControls` object with `setReturningObjFlag` = `true`.
|
||||||
|
*/
|
||||||
|
private class UnsafeSearchControls extends DataFlow::ExprNode {
|
||||||
|
UnsafeSearchControls() {
|
||||||
|
exists(MethodAccess ma |
|
||||||
|
ma.getMethod() instanceof SetReturningObjFlagMethod and
|
||||||
|
ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true and
|
||||||
|
this.asExpr() = ma.getQualifier()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(ConstructorCall cc |
|
||||||
|
cc.getConstructedType() instanceof TypeSearchControls and
|
||||||
|
cc.getArgument(4).(CompileTimeConstantExpr).getBooleanValue() = true and
|
||||||
|
this.asExpr() = cc
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method `SearchControls.setReturningObjFlag`.
|
||||||
|
*/
|
||||||
|
private class SetReturningObjFlagMethod extends Method {
|
||||||
|
SetReturningObjFlagMethod() {
|
||||||
|
this.getDeclaringType() instanceof TypeSearchControls and
|
||||||
|
this.hasName("setReturningObjFlag")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
edges
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:34:16:34:22 | nameStr |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:35:20:35:26 | nameStr |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:36:29:36:35 | nameStr |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:37:16:37:22 | nameStr |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:38:14:38:20 | nameStr |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:39:22:39:28 | nameStr |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:41:16:41:19 | name |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:42:20:42:23 | name |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:43:29:43:32 | name |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:44:16:44:19 | name |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:45:14:45:17 | name |
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:46:22:46:25 | name |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:54:16:54:22 | nameStr |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:55:20:55:26 | nameStr |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:56:16:56:22 | nameStr |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:57:14:57:20 | nameStr |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:58:22:58:28 | nameStr |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:60:16:60:19 | name |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:61:20:61:23 | name |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:62:16:62:19 | name |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:63:14:63:17 | name |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:64:22:64:25 | name |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:72:16:72:22 | nameStr |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:73:20:73:26 | nameStr |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:74:16:74:22 | nameStr |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:75:14:75:20 | nameStr |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:76:22:76:28 | nameStr |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:78:16:78:19 | name |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:79:20:79:23 | name |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:80:16:80:19 | name |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:81:14:81:17 | name |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:82:22:82:25 | name |
|
|
||||||
| JndiInjection.java:86:42:86:69 | nameStr : String | JndiInjection.java:89:16:89:22 | nameStr |
|
|
||||||
| JndiInjection.java:86:42:86:69 | nameStr : String | JndiInjection.java:90:16:90:22 | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:98:16:98:22 | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:99:23:99:29 | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:100:18:100:21 | name |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:101:16:101:19 | name |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:102:14:102:17 | name |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:103:22:103:25 | name |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:104:16:104:22 | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:106:16:106:22 | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:107:16:107:22 | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:108:16:108:22 | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:109:16:109:22 | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:111:25:111:31 | nameStr |
|
|
||||||
| JndiInjection.java:115:41:115:68 | nameStr : String | JndiInjection.java:118:16:118:22 | nameStr |
|
|
||||||
| JndiInjection.java:115:41:115:68 | nameStr : String | JndiInjection.java:119:16:119:22 | nameStr |
|
|
||||||
| JndiInjection.java:123:37:123:63 | urlStr : String | JndiInjection.java:124:33:124:57 | new JMXServiceURL(...) |
|
|
||||||
| JndiInjection.java:123:37:123:63 | urlStr : String | JndiInjection.java:128:5:128:13 | connector |
|
|
||||||
| JndiInjection.java:132:27:132:53 | urlStr : String | JndiInjection.java:135:35:135:40 | urlStr |
|
|
||||||
| JndiInjection.java:140:27:140:53 | urlStr : String | JndiInjection.java:143:41:143:46 | urlStr |
|
|
||||||
| JndiInjection.java:148:52:148:78 | urlStr : String | JndiInjection.java:151:37:151:42 | urlStr |
|
|
||||||
| JndiInjection.java:156:52:156:78 | urlStr : String | JndiInjection.java:159:51:159:56 | urlStr |
|
|
||||||
| JndiInjection.java:164:52:164:78 | urlStr : String | JndiInjection.java:167:51:167:56 | urlStr |
|
|
||||||
nodes
|
|
||||||
| JndiInjection.java:30:38:30:65 | nameStr : String | semmle.label | nameStr : String |
|
|
||||||
| JndiInjection.java:34:16:34:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:35:20:35:26 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:36:29:36:35 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:37:16:37:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:38:14:38:20 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:39:22:39:28 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:41:16:41:19 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:42:20:42:23 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:43:29:43:32 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:44:16:44:19 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:45:14:45:17 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:46:22:46:25 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:50:41:50:68 | nameStr : String | semmle.label | nameStr : String |
|
|
||||||
| JndiInjection.java:54:16:54:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:55:20:55:26 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:56:16:56:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:57:14:57:20 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:58:22:58:28 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:60:16:60:19 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:61:20:61:23 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:62:16:62:19 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:63:14:63:17 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:64:22:64:25 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:68:42:68:69 | nameStr : String | semmle.label | nameStr : String |
|
|
||||||
| JndiInjection.java:72:16:72:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:73:20:73:26 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:74:16:74:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:75:14:75:20 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:76:22:76:28 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:78:16:78:19 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:79:20:79:23 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:80:16:80:19 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:81:14:81:17 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:82:22:82:25 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:86:42:86:69 | nameStr : String | semmle.label | nameStr : String |
|
|
||||||
| JndiInjection.java:89:16:89:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:90:16:90:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:94:42:94:69 | nameStr : String | semmle.label | nameStr : String |
|
|
||||||
| JndiInjection.java:98:16:98:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:99:23:99:29 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:100:18:100:21 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:101:16:101:19 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:102:14:102:17 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:103:22:103:25 | name | semmle.label | name |
|
|
||||||
| JndiInjection.java:104:16:104:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:106:16:106:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:107:16:107:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:108:16:108:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:109:16:109:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:111:25:111:31 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:115:41:115:68 | nameStr : String | semmle.label | nameStr : String |
|
|
||||||
| JndiInjection.java:118:16:118:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:119:16:119:22 | nameStr | semmle.label | nameStr |
|
|
||||||
| JndiInjection.java:123:37:123:63 | urlStr : String | semmle.label | urlStr : String |
|
|
||||||
| JndiInjection.java:124:33:124:57 | new JMXServiceURL(...) | semmle.label | new JMXServiceURL(...) |
|
|
||||||
| JndiInjection.java:128:5:128:13 | connector | semmle.label | connector |
|
|
||||||
| JndiInjection.java:132:27:132:53 | urlStr : String | semmle.label | urlStr : String |
|
|
||||||
| JndiInjection.java:135:35:135:40 | urlStr | semmle.label | urlStr |
|
|
||||||
| JndiInjection.java:140:27:140:53 | urlStr : String | semmle.label | urlStr : String |
|
|
||||||
| JndiInjection.java:143:41:143:46 | urlStr | semmle.label | urlStr |
|
|
||||||
| JndiInjection.java:148:52:148:78 | urlStr : String | semmle.label | urlStr : String |
|
|
||||||
| JndiInjection.java:151:37:151:42 | urlStr | semmle.label | urlStr |
|
|
||||||
| JndiInjection.java:156:52:156:78 | urlStr : String | semmle.label | urlStr : String |
|
|
||||||
| JndiInjection.java:159:51:159:56 | urlStr | semmle.label | urlStr |
|
|
||||||
| JndiInjection.java:164:52:164:78 | urlStr : String | semmle.label | urlStr : String |
|
|
||||||
| JndiInjection.java:167:51:167:56 | urlStr | semmle.label | urlStr |
|
|
||||||
#select
|
|
||||||
| JndiInjection.java:34:16:34:22 | nameStr | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:34:16:34:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:35:20:35:26 | nameStr | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:35:20:35:26 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:36:29:36:35 | nameStr | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:36:29:36:35 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:37:16:37:22 | nameStr | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:37:16:37:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:38:14:38:20 | nameStr | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:38:14:38:20 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:39:22:39:28 | nameStr | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:39:22:39:28 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:41:16:41:19 | name | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:41:16:41:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:42:20:42:23 | name | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:42:20:42:23 | name | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:43:29:43:32 | name | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:43:29:43:32 | name | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:44:16:44:19 | name | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:44:16:44:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:45:14:45:17 | name | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:45:14:45:17 | name | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:46:22:46:25 | name | JndiInjection.java:30:38:30:65 | nameStr : String | JndiInjection.java:46:22:46:25 | name | JNDI lookup might include name from $@. | JndiInjection.java:30:38:30:65 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:54:16:54:22 | nameStr | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:54:16:54:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:55:20:55:26 | nameStr | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:55:20:55:26 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:56:16:56:22 | nameStr | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:56:16:56:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:57:14:57:20 | nameStr | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:57:14:57:20 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:58:22:58:28 | nameStr | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:58:22:58:28 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:60:16:60:19 | name | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:60:16:60:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:61:20:61:23 | name | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:61:20:61:23 | name | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:62:16:62:19 | name | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:62:16:62:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:63:14:63:17 | name | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:63:14:63:17 | name | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:64:22:64:25 | name | JndiInjection.java:50:41:50:68 | nameStr : String | JndiInjection.java:64:22:64:25 | name | JNDI lookup might include name from $@. | JndiInjection.java:50:41:50:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:72:16:72:22 | nameStr | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:72:16:72:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:73:20:73:26 | nameStr | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:73:20:73:26 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:74:16:74:22 | nameStr | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:74:16:74:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:75:14:75:20 | nameStr | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:75:14:75:20 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:76:22:76:28 | nameStr | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:76:22:76:28 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:78:16:78:19 | name | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:78:16:78:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:79:20:79:23 | name | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:79:20:79:23 | name | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:80:16:80:19 | name | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:80:16:80:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:81:14:81:17 | name | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:81:14:81:17 | name | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:82:22:82:25 | name | JndiInjection.java:68:42:68:69 | nameStr : String | JndiInjection.java:82:22:82:25 | name | JNDI lookup might include name from $@. | JndiInjection.java:68:42:68:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:89:16:89:22 | nameStr | JndiInjection.java:86:42:86:69 | nameStr : String | JndiInjection.java:89:16:89:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:86:42:86:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:90:16:90:22 | nameStr | JndiInjection.java:86:42:86:69 | nameStr : String | JndiInjection.java:90:16:90:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:86:42:86:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:98:16:98:22 | nameStr | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:98:16:98:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:99:23:99:29 | nameStr | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:99:23:99:29 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:100:18:100:21 | name | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:100:18:100:21 | name | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:101:16:101:19 | name | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:101:16:101:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:102:14:102:17 | name | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:102:14:102:17 | name | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:103:22:103:25 | name | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:103:22:103:25 | name | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:104:16:104:22 | nameStr | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:104:16:104:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:106:16:106:22 | nameStr | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:106:16:106:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:107:16:107:22 | nameStr | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:107:16:107:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:108:16:108:22 | nameStr | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:108:16:108:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:109:16:109:22 | nameStr | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:109:16:109:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:111:25:111:31 | nameStr | JndiInjection.java:94:42:94:69 | nameStr : String | JndiInjection.java:111:25:111:31 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:94:42:94:69 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:118:16:118:22 | nameStr | JndiInjection.java:115:41:115:68 | nameStr : String | JndiInjection.java:118:16:118:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:115:41:115:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:119:16:119:22 | nameStr | JndiInjection.java:115:41:115:68 | nameStr : String | JndiInjection.java:119:16:119:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:115:41:115:68 | nameStr | this user input |
|
|
||||||
| JndiInjection.java:124:33:124:57 | new JMXServiceURL(...) | JndiInjection.java:123:37:123:63 | urlStr : String | JndiInjection.java:124:33:124:57 | new JMXServiceURL(...) | JNDI lookup might include name from $@. | JndiInjection.java:123:37:123:63 | urlStr | this user input |
|
|
||||||
| JndiInjection.java:128:5:128:13 | connector | JndiInjection.java:123:37:123:63 | urlStr : String | JndiInjection.java:128:5:128:13 | connector | JNDI lookup might include name from $@. | JndiInjection.java:123:37:123:63 | urlStr | this user input |
|
|
||||||
| JndiInjection.java:135:35:135:40 | urlStr | JndiInjection.java:132:27:132:53 | urlStr : String | JndiInjection.java:135:35:135:40 | urlStr | JNDI lookup might include name from $@. | JndiInjection.java:132:27:132:53 | urlStr | this user input |
|
|
||||||
| JndiInjection.java:143:41:143:46 | urlStr | JndiInjection.java:140:27:140:53 | urlStr : String | JndiInjection.java:143:41:143:46 | urlStr | JNDI lookup might include name from $@. | JndiInjection.java:140:27:140:53 | urlStr | this user input |
|
|
||||||
| JndiInjection.java:151:37:151:42 | urlStr | JndiInjection.java:148:52:148:78 | urlStr : String | JndiInjection.java:151:37:151:42 | urlStr | JNDI lookup might include name from $@. | JndiInjection.java:148:52:148:78 | urlStr | this user input |
|
|
||||||
| JndiInjection.java:159:51:159:56 | urlStr | JndiInjection.java:156:52:156:78 | urlStr : String | JndiInjection.java:159:51:159:56 | urlStr | JNDI lookup might include name from $@. | JndiInjection.java:156:52:156:78 | urlStr | this user input |
|
|
||||||
| JndiInjection.java:167:51:167:56 | urlStr | JndiInjection.java:164:52:164:78 | urlStr : String | JndiInjection.java:167:51:167:56 | urlStr | JNDI lookup might include name from $@. | JndiInjection.java:164:52:164:78 | urlStr | this user input |
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
import java.io.IOException;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import javax.management.remote.JMXConnector;
|
|
||||||
import javax.management.remote.JMXConnectorFactory;
|
|
||||||
import javax.management.remote.JMXServiceURL;
|
|
||||||
import javax.naming.CompositeName;
|
|
||||||
import javax.naming.CompoundName;
|
|
||||||
import javax.naming.Context;
|
|
||||||
import javax.naming.InitialContext;
|
|
||||||
import javax.naming.Name;
|
|
||||||
import javax.naming.NamingException;
|
|
||||||
import javax.naming.directory.InitialDirContext;
|
|
||||||
import javax.naming.directory.SearchControls;
|
|
||||||
import javax.naming.ldap.InitialLdapContext;
|
|
||||||
|
|
||||||
import org.springframework.jndi.JndiTemplate;
|
|
||||||
import org.springframework.ldap.core.AttributesMapper;
|
|
||||||
import org.springframework.ldap.core.ContextMapper;
|
|
||||||
import org.springframework.ldap.core.LdapTemplate;
|
|
||||||
import org.springframework.ldap.core.NameClassPairCallbackHandler;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class JndiInjection {
|
|
||||||
@RequestMapping
|
|
||||||
public void testInitialContextBad1(@RequestParam String nameStr) throws NamingException {
|
|
||||||
Name name = new CompositeName(nameStr);
|
|
||||||
InitialContext ctx = new InitialContext();
|
|
||||||
|
|
||||||
ctx.lookup(nameStr);
|
|
||||||
ctx.lookupLink(nameStr);
|
|
||||||
InitialContext.doLookup(nameStr);
|
|
||||||
ctx.rename(nameStr, "");
|
|
||||||
ctx.list(nameStr);
|
|
||||||
ctx.listBindings(nameStr);
|
|
||||||
|
|
||||||
ctx.lookup(name);
|
|
||||||
ctx.lookupLink(name);
|
|
||||||
InitialContext.doLookup(name);
|
|
||||||
ctx.rename(name, null);
|
|
||||||
ctx.list(name);
|
|
||||||
ctx.listBindings(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testInitialDirContextBad1(@RequestParam String nameStr) throws NamingException {
|
|
||||||
Name name = new CompoundName(nameStr, new Properties());
|
|
||||||
InitialDirContext ctx = new InitialDirContext();
|
|
||||||
|
|
||||||
ctx.lookup(nameStr);
|
|
||||||
ctx.lookupLink(nameStr);
|
|
||||||
ctx.rename(nameStr, "");
|
|
||||||
ctx.list(nameStr);
|
|
||||||
ctx.listBindings(nameStr);
|
|
||||||
|
|
||||||
ctx.lookup(name);
|
|
||||||
ctx.lookupLink(name);
|
|
||||||
ctx.rename(name, null);
|
|
||||||
ctx.list(name);
|
|
||||||
ctx.listBindings(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testInitialLdapContextBad1(@RequestParam String nameStr) throws NamingException {
|
|
||||||
Name name = new CompositeName(nameStr);
|
|
||||||
InitialLdapContext ctx = new InitialLdapContext();
|
|
||||||
|
|
||||||
ctx.lookup(nameStr);
|
|
||||||
ctx.lookupLink(nameStr);
|
|
||||||
ctx.rename(nameStr, "");
|
|
||||||
ctx.list(nameStr);
|
|
||||||
ctx.listBindings(nameStr);
|
|
||||||
|
|
||||||
ctx.lookup(name);
|
|
||||||
ctx.lookupLink(name);
|
|
||||||
ctx.rename(name, null);
|
|
||||||
ctx.list(name);
|
|
||||||
ctx.listBindings(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testSpringJndiTemplateBad1(@RequestParam String nameStr) throws NamingException {
|
|
||||||
JndiTemplate ctx = new JndiTemplate();
|
|
||||||
|
|
||||||
ctx.lookup(nameStr);
|
|
||||||
ctx.lookup(nameStr, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testSpringLdapTemplateBad1(@RequestParam String nameStr) throws NamingException {
|
|
||||||
LdapTemplate ctx = new LdapTemplate();
|
|
||||||
Name name = new CompositeName(nameStr);
|
|
||||||
|
|
||||||
ctx.lookup(nameStr);
|
|
||||||
ctx.lookupContext(nameStr);
|
|
||||||
ctx.findByDn(name, null);
|
|
||||||
ctx.rename(name, null);
|
|
||||||
ctx.list(name);
|
|
||||||
ctx.listBindings(name);
|
|
||||||
ctx.unbind(nameStr, true);
|
|
||||||
|
|
||||||
ctx.search(nameStr, "", 0, true, null);
|
|
||||||
ctx.search(nameStr, "", 0, new String[] {}, (ContextMapper<Object>) new Object());
|
|
||||||
ctx.search(nameStr, "", 0, (ContextMapper<Object>) new Object());
|
|
||||||
ctx.search(nameStr, "", (ContextMapper) new Object());
|
|
||||||
|
|
||||||
ctx.searchForObject(nameStr, "", (ContextMapper) new Object());
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testShiroJndiTemplateBad1(@RequestParam String nameStr) throws NamingException {
|
|
||||||
org.apache.shiro.jndi.JndiTemplate ctx = new org.apache.shiro.jndi.JndiTemplate();
|
|
||||||
|
|
||||||
ctx.lookup(nameStr);
|
|
||||||
ctx.lookup(nameStr, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testJMXServiceUrlBad1(@RequestParam String urlStr) throws IOException {
|
|
||||||
JMXConnectorFactory.connect(new JMXServiceURL(urlStr));
|
|
||||||
|
|
||||||
JMXServiceURL url = new JMXServiceURL(urlStr);
|
|
||||||
JMXConnector connector = JMXConnectorFactory.newJMXConnector(url, null);
|
|
||||||
connector.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testEnvBad1(@RequestParam String urlStr) throws NamingException {
|
|
||||||
Hashtable<String, String> env = new Hashtable<String, String>();
|
|
||||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
|
||||||
env.put(Context.PROVIDER_URL, urlStr);
|
|
||||||
new InitialContext(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testEnvBad2(@RequestParam String urlStr) throws NamingException {
|
|
||||||
Hashtable<String, String> env = new Hashtable<String, String>();
|
|
||||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
|
||||||
env.put("java.naming.provider.url", urlStr);
|
|
||||||
new InitialDirContext(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testSpringJndiTemplatePropertiesBad1(@RequestParam String urlStr) throws NamingException {
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
|
||||||
props.put(Context.PROVIDER_URL, urlStr);
|
|
||||||
new JndiTemplate(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testSpringJndiTemplatePropertiesBad2(@RequestParam String urlStr) throws NamingException {
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
|
||||||
props.setProperty("java.naming.provider.url", urlStr);
|
|
||||||
new JndiTemplate(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testSpringJndiTemplatePropertiesBad3(@RequestParam String urlStr) throws NamingException {
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
|
||||||
props.setProperty("java.naming.provider.url", urlStr);
|
|
||||||
JndiTemplate template = new JndiTemplate();
|
|
||||||
template.setEnvironment(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testSpringLdapTemplateOk1(@RequestParam String nameStr) throws NamingException {
|
|
||||||
LdapTemplate ctx = new LdapTemplate();
|
|
||||||
|
|
||||||
ctx.unbind(nameStr);
|
|
||||||
ctx.unbind(nameStr, false);
|
|
||||||
|
|
||||||
ctx.search(nameStr, "", 0, false, null);
|
|
||||||
ctx.search(nameStr, "", new SearchControls(), (NameClassPairCallbackHandler) new Object());
|
|
||||||
ctx.search(nameStr, "", new SearchControls(), (NameClassPairCallbackHandler) new Object(), null);
|
|
||||||
ctx.search(nameStr, "", (NameClassPairCallbackHandler) new Object());
|
|
||||||
ctx.search(nameStr, "", 0, new String[] {}, (AttributesMapper<Object>) new Object());
|
|
||||||
ctx.search(nameStr, "", 0, (AttributesMapper<Object>) new Object());
|
|
||||||
ctx.search(nameStr, "", (AttributesMapper) new Object());
|
|
||||||
ctx.search(nameStr, "", new SearchControls(), (ContextMapper) new Object());
|
|
||||||
ctx.search(nameStr, "", new SearchControls(), (AttributesMapper) new Object());
|
|
||||||
ctx.search(nameStr, "", new SearchControls(), (ContextMapper) new Object(), null);
|
|
||||||
ctx.search(nameStr, "", new SearchControls(), (AttributesMapper) new Object(), null);
|
|
||||||
|
|
||||||
ctx.searchForObject(nameStr, "", new SearchControls(), (ContextMapper) new Object());
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testEnvOk1(@RequestParam String urlStr) throws NamingException {
|
|
||||||
Hashtable<String, String> env = new Hashtable<String, String>();
|
|
||||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
|
||||||
env.put(Context.SECURITY_PRINCIPAL, urlStr);
|
|
||||||
new InitialContext(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping
|
|
||||||
public void testEnvOk2(@RequestParam String urlStr) throws NamingException {
|
|
||||||
Hashtable<String, String> env = new Hashtable<String, String>();
|
|
||||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
|
||||||
env.put("java.naming.security.principal", urlStr);
|
|
||||||
new InitialContext(env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
experimental/Security/CWE/CWE-074/JndiInjection.ql
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../../stubs/spring-ldap-2.3.2
|
|
||||||
264
java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.java
Normal file
264
java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.java
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.management.remote.JMXConnector;
|
||||||
|
import javax.management.remote.JMXConnectorFactory;
|
||||||
|
import javax.management.remote.JMXServiceURL;
|
||||||
|
import javax.naming.CompositeName;
|
||||||
|
import javax.naming.CompoundName;
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.InitialContext;
|
||||||
|
import javax.naming.Name;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
import javax.naming.directory.SearchControls;
|
||||||
|
import javax.naming.ldap.InitialLdapContext;
|
||||||
|
|
||||||
|
import org.springframework.jndi.JndiTemplate;
|
||||||
|
import org.springframework.ldap.core.AttributesMapper;
|
||||||
|
import org.springframework.ldap.core.ContextMapper;
|
||||||
|
import org.springframework.ldap.core.DirContextProcessor;
|
||||||
|
import org.springframework.ldap.core.LdapTemplate;
|
||||||
|
import org.springframework.ldap.core.NameClassPairCallbackHandler;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class JndiInjectionTest {
|
||||||
|
@RequestMapping
|
||||||
|
public void testInitialContextBad1(@RequestParam String nameStr) throws NamingException {
|
||||||
|
Name name = new CompositeName(nameStr);
|
||||||
|
InitialContext ctx = new InitialContext();
|
||||||
|
|
||||||
|
ctx.lookup(nameStr); // $hasJndiInjection
|
||||||
|
ctx.lookupLink(nameStr); // $hasJndiInjection
|
||||||
|
InitialContext.doLookup(nameStr); // $hasJndiInjection
|
||||||
|
ctx.rename(nameStr, ""); // $hasJndiInjection
|
||||||
|
ctx.list(nameStr); // $hasJndiInjection
|
||||||
|
ctx.listBindings(nameStr); // $hasJndiInjection
|
||||||
|
|
||||||
|
ctx.lookup(name); // $hasJndiInjection
|
||||||
|
ctx.lookupLink(name); // $hasJndiInjection
|
||||||
|
InitialContext.doLookup(name); // $hasJndiInjection
|
||||||
|
ctx.rename(name, null); // $hasJndiInjection
|
||||||
|
ctx.list(name); // $hasJndiInjection
|
||||||
|
ctx.listBindings(name); // $hasJndiInjection
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testDirContextBad1(@RequestParam String nameStr) throws NamingException {
|
||||||
|
Name name = new CompoundName(nameStr, new Properties());
|
||||||
|
DirContext ctx = new InitialDirContext();
|
||||||
|
|
||||||
|
ctx.lookup(nameStr); // $hasJndiInjection
|
||||||
|
ctx.lookupLink(nameStr); // $hasJndiInjection
|
||||||
|
ctx.rename(nameStr, ""); // $hasJndiInjection
|
||||||
|
ctx.list(nameStr); // $hasJndiInjection
|
||||||
|
ctx.listBindings(nameStr); // $hasJndiInjection
|
||||||
|
|
||||||
|
ctx.lookup(name); // $hasJndiInjection
|
||||||
|
ctx.lookupLink(name); // $hasJndiInjection
|
||||||
|
ctx.rename(name, null); // $hasJndiInjection
|
||||||
|
ctx.list(name); // $hasJndiInjection
|
||||||
|
ctx.listBindings(name); // $hasJndiInjection
|
||||||
|
|
||||||
|
SearchControls searchControls = new SearchControls();
|
||||||
|
searchControls.setReturningObjFlag(true);
|
||||||
|
ctx.search(nameStr, "", searchControls); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", new Object[] {}, searchControls); // $hasJndiInjection
|
||||||
|
|
||||||
|
SearchControls searchControls2 = new SearchControls(1, 0, 0, null, true, false);
|
||||||
|
ctx.search(nameStr, "", searchControls2); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", new Object[] {}, searchControls2); // $hasJndiInjection
|
||||||
|
|
||||||
|
SearchControls searchControls3 = new SearchControls(1, 0, 0, null, false, false);
|
||||||
|
ctx.search(nameStr, "", searchControls3); // Safe
|
||||||
|
ctx.search(nameStr, "", new Object[] {}, searchControls3); // Safe
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testInitialLdapContextBad1(@RequestParam String nameStr) throws NamingException {
|
||||||
|
Name name = new CompositeName(nameStr);
|
||||||
|
InitialLdapContext ctx = new InitialLdapContext();
|
||||||
|
|
||||||
|
ctx.lookup(nameStr); // $hasJndiInjection
|
||||||
|
ctx.lookupLink(nameStr); // $hasJndiInjection
|
||||||
|
ctx.rename(nameStr, ""); // $hasJndiInjection
|
||||||
|
ctx.list(nameStr); // $hasJndiInjection
|
||||||
|
ctx.listBindings(nameStr); // $hasJndiInjection
|
||||||
|
|
||||||
|
ctx.lookup(name); // $hasJndiInjection
|
||||||
|
ctx.lookupLink(name); // $hasJndiInjection
|
||||||
|
ctx.rename(name, null); // $hasJndiInjection
|
||||||
|
ctx.list(name); // $hasJndiInjection
|
||||||
|
ctx.listBindings(name); // $hasJndiInjection
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testSpringJndiTemplateBad1(@RequestParam String nameStr) throws NamingException {
|
||||||
|
JndiTemplate ctx = new JndiTemplate();
|
||||||
|
|
||||||
|
ctx.lookup(nameStr); // $hasJndiInjection
|
||||||
|
ctx.lookup(nameStr, null); // $hasJndiInjection
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testSpringLdapTemplateBad1(@RequestParam String nameStr) throws NamingException {
|
||||||
|
LdapTemplate ctx = new LdapTemplate();
|
||||||
|
Name name = new CompositeName().add(nameStr);
|
||||||
|
|
||||||
|
ctx.lookup(nameStr); // $hasJndiInjection
|
||||||
|
ctx.lookupContext(nameStr); // $hasJndiInjection
|
||||||
|
ctx.findByDn(name, null); // $hasJndiInjection
|
||||||
|
ctx.rename(name, null); // $hasJndiInjection
|
||||||
|
ctx.list(name); // $hasJndiInjection
|
||||||
|
ctx.listBindings(name); // $hasJndiInjection
|
||||||
|
ctx.unbind(nameStr, true); // $hasJndiInjection
|
||||||
|
|
||||||
|
ctx.search(nameStr, "", 0, true, null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", 0, new String[] {}, (ContextMapper<Object>) null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", 0, (ContextMapper<Object>) null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", (ContextMapper<Object>) null); // $hasJndiInjection
|
||||||
|
|
||||||
|
SearchControls searchControls = new SearchControls();
|
||||||
|
searchControls.setReturningObjFlag(true);
|
||||||
|
ctx.search(nameStr, "", searchControls, (AttributesMapper<Object>) null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", searchControls, (AttributesMapper<Object>) null, // $hasJndiInjection
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
ctx.search(nameStr, "", searchControls, (ContextMapper<Object>) null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", searchControls, (ContextMapper<Object>) null, // $hasJndiInjection
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
ctx.search(nameStr, "", searchControls, (NameClassPairCallbackHandler) null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", searchControls, (NameClassPairCallbackHandler) null, // $hasJndiInjection
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
|
||||||
|
SearchControls searchControls2 = new SearchControls(1, 0, 0, null, true, false);
|
||||||
|
ctx.search(nameStr, "", searchControls2, (AttributesMapper<Object>) null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", searchControls2, (AttributesMapper<Object>) null, // $hasJndiInjection
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
ctx.search(nameStr, "", searchControls2, (ContextMapper<Object>) null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", searchControls2, (ContextMapper<Object>) null, // $hasJndiInjection
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
ctx.search(nameStr, "", searchControls2, (NameClassPairCallbackHandler) null); // $hasJndiInjection
|
||||||
|
ctx.search(nameStr, "", searchControls2, (NameClassPairCallbackHandler) null, // $hasJndiInjection
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
|
||||||
|
SearchControls searchControls3 = new SearchControls(1, 0, 0, null, false, false);
|
||||||
|
ctx.search(nameStr, "", searchControls3, (AttributesMapper<Object>) null); // Safe
|
||||||
|
ctx.search(nameStr, "", searchControls3, (AttributesMapper<Object>) null, // Safe
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
ctx.search(nameStr, "", searchControls3, (ContextMapper<Object>) null); // Safe
|
||||||
|
ctx.search(nameStr, "", searchControls3, (ContextMapper<Object>) null, // Safe
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
ctx.search(nameStr, "", searchControls3, (NameClassPairCallbackHandler) null); // Safe
|
||||||
|
ctx.search(nameStr, "", searchControls3, (NameClassPairCallbackHandler) null, // Safe
|
||||||
|
(DirContextProcessor) null);
|
||||||
|
|
||||||
|
ctx.searchForObject(nameStr, "", (ContextMapper<Object>) null); // $hasJndiInjection
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testShiroJndiTemplateBad1(@RequestParam String nameStr) throws NamingException {
|
||||||
|
org.apache.shiro.jndi.JndiTemplate ctx = new org.apache.shiro.jndi.JndiTemplate();
|
||||||
|
|
||||||
|
ctx.lookup(nameStr); // $hasJndiInjection
|
||||||
|
ctx.lookup(nameStr, null); // $hasJndiInjection
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testJMXServiceUrlBad1(@RequestParam String urlStr) throws IOException {
|
||||||
|
JMXConnectorFactory.connect(new JMXServiceURL(urlStr)); // $hasJndiInjection
|
||||||
|
|
||||||
|
JMXServiceURL url = new JMXServiceURL(urlStr);
|
||||||
|
JMXConnector connector = JMXConnectorFactory.newJMXConnector(url, null);
|
||||||
|
connector.connect(); // $hasJndiInjection
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testEnvBad1(@RequestParam String urlStr) throws NamingException {
|
||||||
|
Hashtable<String, String> env = new Hashtable<String, String>();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
||||||
|
env.put(Context.PROVIDER_URL, urlStr); // $hasJndiInjection
|
||||||
|
new InitialContext(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testEnvBad2(@RequestParam String urlStr) throws NamingException {
|
||||||
|
Hashtable<String, String> env = new Hashtable<String, String>();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
||||||
|
env.put("java.naming.provider.url", urlStr); // $hasJndiInjection
|
||||||
|
new InitialDirContext(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testSpringJndiTemplatePropertiesBad1(@RequestParam String urlStr)
|
||||||
|
throws NamingException {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
||||||
|
props.put(Context.PROVIDER_URL, urlStr); // $hasJndiInjection
|
||||||
|
new JndiTemplate(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testSpringJndiTemplatePropertiesBad2(@RequestParam String urlStr)
|
||||||
|
throws NamingException {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
|
||||||
|
"com.sun.jndi.rmi.registry.RegistryContextFactory");
|
||||||
|
props.setProperty("java.naming.provider.url", urlStr); // $hasJndiInjection
|
||||||
|
new JndiTemplate(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testSpringJndiTemplatePropertiesBad3(@RequestParam String urlStr)
|
||||||
|
throws NamingException {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
|
||||||
|
"com.sun.jndi.rmi.registry.RegistryContextFactory");
|
||||||
|
props.setProperty("java.naming.provider.url", urlStr); // $hasJndiInjection
|
||||||
|
JndiTemplate template = new JndiTemplate();
|
||||||
|
template.setEnvironment(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testSpringLdapTemplateOk1(@RequestParam String nameStr) throws NamingException {
|
||||||
|
LdapTemplate ctx = new LdapTemplate();
|
||||||
|
|
||||||
|
ctx.unbind(nameStr); // Safe
|
||||||
|
ctx.unbind(nameStr, false); // Safe
|
||||||
|
|
||||||
|
ctx.search(nameStr, "", 0, false, null); // Safe
|
||||||
|
ctx.search(nameStr, "", new SearchControls(), (NameClassPairCallbackHandler) new Object()); // Safe
|
||||||
|
ctx.search(nameStr, "", new SearchControls(), (NameClassPairCallbackHandler) new Object(), // Safe
|
||||||
|
null);
|
||||||
|
ctx.search(nameStr, "", (NameClassPairCallbackHandler) new Object()); // Safe
|
||||||
|
ctx.search(nameStr, "", 0, new String[] {}, (AttributesMapper<Object>) new Object()); // Safe
|
||||||
|
ctx.search(nameStr, "", 0, (AttributesMapper<Object>) new Object()); // Safe
|
||||||
|
ctx.search(nameStr, "", (AttributesMapper) new Object()); // Safe
|
||||||
|
ctx.search(nameStr, "", new SearchControls(), (ContextMapper) new Object()); // Safe
|
||||||
|
ctx.search(nameStr, "", new SearchControls(), (AttributesMapper) new Object()); // Safe
|
||||||
|
ctx.search(nameStr, "", new SearchControls(), (ContextMapper) new Object(), null); // Safe
|
||||||
|
ctx.search(nameStr, "", new SearchControls(), (AttributesMapper) new Object(), null); // Safe
|
||||||
|
|
||||||
|
ctx.searchForObject(nameStr, "", new SearchControls(), (ContextMapper) new Object()); // Safe
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testEnvOk1(@RequestParam String urlStr) throws NamingException {
|
||||||
|
Hashtable<String, String> env = new Hashtable<String, String>();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
||||||
|
env.put(Context.SECURITY_PRINCIPAL, urlStr); // Safe
|
||||||
|
new InitialContext(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public void testEnvOk2(@RequestParam String urlStr) throws NamingException {
|
||||||
|
Hashtable<String, String> env = new Hashtable<String, String>();
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
|
||||||
|
env.put("java.naming.security.principal", urlStr); // Safe
|
||||||
|
new InitialContext(env);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import java
|
||||||
|
import semmle.code.java.security.JndiInjectionQuery
|
||||||
|
import TestUtilities.InlineExpectationsTest
|
||||||
|
|
||||||
|
class HasJndiInjectionTest extends InlineExpectationsTest {
|
||||||
|
HasJndiInjectionTest() { this = "HasJndiInjectionTest" }
|
||||||
|
|
||||||
|
override string getARelevantTag() { result = "hasJndiInjection" }
|
||||||
|
|
||||||
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
|
tag = "hasJndiInjection" and
|
||||||
|
exists(DataFlow::Node src, DataFlow::Node sink, JndiInjectionFlowConfig conf |
|
||||||
|
conf.hasFlow(src, sink)
|
||||||
|
|
|
||||||
|
sink.getLocation() = location and
|
||||||
|
element = sink.toString() and
|
||||||
|
value = ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
1
java/ql/test/query-tests/security/CWE-074/options
Normal file
1
java/ql/test/query-tests/security/CWE-074/options
Normal file
@@ -0,0 +1 @@
|
|||||||
|
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../stubs/spring-ldap-2.3.2
|
||||||
@@ -1,3 +1,84 @@
|
|||||||
package org.springframework.ldap.core;
|
package org.springframework.ldap.core;
|
||||||
|
|
||||||
public interface LdapOperations {}
|
import java.util.*;
|
||||||
|
|
||||||
|
import javax.naming.Name;
|
||||||
|
import javax.naming.directory.SearchControls;
|
||||||
|
|
||||||
|
import org.springframework.ldap.filter.Filter;
|
||||||
|
|
||||||
|
import org.springframework.ldap.query.LdapQuery;
|
||||||
|
|
||||||
|
public interface LdapOperations {
|
||||||
|
void authenticate(LdapQuery query, String password);
|
||||||
|
|
||||||
|
boolean authenticate(Name base, String filter, String password);
|
||||||
|
|
||||||
|
<T> List<T> find(Name base, Filter filter, SearchControls searchControls, final Class<T> clazz);
|
||||||
|
|
||||||
|
<T> List<T> find(LdapQuery query, Class<T> clazz);
|
||||||
|
|
||||||
|
<T> T findOne(LdapQuery query, Class<T> clazz);
|
||||||
|
|
||||||
|
void search(String base, String filter, int searchScope, boolean returningObjFlag,
|
||||||
|
NameClassPairCallbackHandler handler);
|
||||||
|
|
||||||
|
void search(final String base, final String filter, final SearchControls controls,
|
||||||
|
NameClassPairCallbackHandler handler);
|
||||||
|
|
||||||
|
void search(final String base, final String filter, final SearchControls controls,
|
||||||
|
NameClassPairCallbackHandler handler, DirContextProcessor processor);
|
||||||
|
|
||||||
|
void search(String base, String filter, NameClassPairCallbackHandler handler);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, int searchScope, String[] attrs,
|
||||||
|
AttributesMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, int searchScope, AttributesMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, AttributesMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, int searchScope, String[] attrs,
|
||||||
|
ContextMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, int searchScope, ContextMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, ContextMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, SearchControls controls,
|
||||||
|
ContextMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, SearchControls controls,
|
||||||
|
AttributesMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, SearchControls controls,
|
||||||
|
AttributesMapper<T> mapper, DirContextProcessor processor);
|
||||||
|
|
||||||
|
<T> List<T> search(String base, String filter, SearchControls controls, ContextMapper<T> mapper,
|
||||||
|
DirContextProcessor processor);
|
||||||
|
|
||||||
|
DirContextOperations searchForContext(LdapQuery query);
|
||||||
|
|
||||||
|
<T> T searchForObject(Name base, String filter, ContextMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> T searchForObject(String base, String filter, ContextMapper<T> mapper);
|
||||||
|
|
||||||
|
<T> T searchForObject(String base, String filter, SearchControls searchControls,
|
||||||
|
ContextMapper<T> mapper);
|
||||||
|
|
||||||
|
Object lookup(final String dn);
|
||||||
|
|
||||||
|
DirContextOperations lookupContext(String dn);
|
||||||
|
|
||||||
|
<T> T findByDn(Name dn, final Class<T> clazz);
|
||||||
|
|
||||||
|
void rename(final Name oldDn, final Name newDn);
|
||||||
|
|
||||||
|
List<String> list(final Name base);
|
||||||
|
|
||||||
|
List<String> listBindings(final Name base);
|
||||||
|
|
||||||
|
void unbind(final String dn);
|
||||||
|
|
||||||
|
void unbind(final String dn, boolean recursive);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user