mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
CodeQL query to detect JNDI injections
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
|
||||
public void jndiLookup(HttpServletRequest request) throws NamingException {
|
||||
String name = request.getParameter("name");
|
||||
|
||||
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, "rmi://trusted-server:1099");
|
||||
InitialContext ctx = new InitialContext(env);
|
||||
|
||||
// BAD: User input used in lookup
|
||||
ctx.lookup(name);
|
||||
|
||||
// GOOD: The name is validated before being used in lookup
|
||||
if (isValid(name)) {
|
||||
ctx.lookup(name);
|
||||
} else {
|
||||
// Reject the request
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>The Java Naming and Directory Interface (JNDI) is a Java API for a directory service that allows
|
||||
Java software clients to discover and look up data and resources (in the form of Java objects) via
|
||||
a name. If the name being used to look up the data is controlled by the user, it can point to a
|
||||
malicious server, which can return an arbitrary object. In the worst case, this can allow remote
|
||||
code execution.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>The general recommendation is to not pass 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
|
||||
sure that it's not in the form of an absolute URL or that it's the URL pointing to a trused server.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>In the following examples, the code accepts a name from the user, which it uses to look up an
|
||||
object.</p>
|
||||
|
||||
<p>In the first example, the user provided name is used to look up an object.</p>
|
||||
|
||||
<p>The second example validates the name before using it to look up an object.</p>
|
||||
|
||||
<sample src="JndiInjection.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>Oracle: <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jndi/">Java Naming and Directory Interface (JNDI)</a>.</li>
|
||||
<li>Black Hat materials: <a href="https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf">A Journey from JNDI/LDAP Manipulation to Remote Code Execution Dream Land</a>.</li>
|
||||
<li>Veracode: <a href="https://www.veracode.com/blog/research/exploiting-jndi-injections-java">Exploiting JNDI Injections in Java</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @name JNDI lookup with user-controlled name
|
||||
* @description Doing a JNDI lookup with user-controlled name can lead to download an untrusted
|
||||
* object and to execution of arbitrary code.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/jndi-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-074
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import JndiInjectionLib
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, JndiInjectionFlowConfig conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "JNDI lookup might include name from $@.", source.getNode(),
|
||||
"this user input"
|
||||
@@ -0,0 +1,91 @@
|
||||
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 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) {
|
||||
compositeNameStep(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 springSinkMethod(Method m, int index) {
|
||||
m.getDeclaringType() instanceof TypeSpringJndiTemplate and
|
||||
m.hasName("lookup") 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
|
||||
}
|
||||
|
||||
/** Holds if parameter at index `index` in method `m` is JNDI injection sink. */
|
||||
predicate jndiInjectionSinkMethod(Method m, int index) {
|
||||
jndiSinkMethod(m, index) or
|
||||
springSinkMethod(m, index) or
|
||||
shiroSinkMethod(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(m, index)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `CompositeName`,
|
||||
* i.e. `new CompositeName(tainted)`.
|
||||
*/
|
||||
predicate compositeNameStep(ExprNode n1, ExprNode n2) {
|
||||
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeCompositeName |
|
||||
n1.asExpr() = cc.getAnArgument() and
|
||||
n2.asExpr() = cc
|
||||
)
|
||||
}
|
||||
4
java/ql/src/experimental/qlpack.yml
Normal file
4
java/ql/src/experimental/qlpack.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
name: codeql-java-experimental
|
||||
version: 0.0.0
|
||||
libraryPathDependencies: codeql-java
|
||||
extractor: java
|
||||
@@ -0,0 +1,11 @@
|
||||
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") }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import java
|
||||
|
||||
/** The class `org.apache.shiro.jndi.JndiTemplate`. */
|
||||
class TypeShiroJndiTemplate extends Class {
|
||||
TypeShiroJndiTemplate() { this.hasQualifiedName("org.apache.shiro.jndi", "JndiTemplate") }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import java
|
||||
|
||||
/** The class `org.springframework.jndi.JndiTemplate`. */
|
||||
class TypeSpringJndiTemplate extends Class {
|
||||
TypeSpringJndiTemplate() { this.hasQualifiedName("org.springframework.jndi", "JndiTemplate") }
|
||||
}
|
||||
4
java/ql/test/experimental/qlpack.yml
Normal file
4
java/ql/test/experimental/qlpack.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
name: codeql-java-experimental-tests
|
||||
version: 0.0.0
|
||||
libraryPathDependencies: codeql-java-experimental
|
||||
extractor: java
|
||||
@@ -0,0 +1,116 @@
|
||||
edges
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:16:16:16:22 | nameStr |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:17:20:17:26 | nameStr |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:18:29:18:35 | nameStr |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:19:16:19:22 | nameStr |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:20:14:20:20 | nameStr |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:21:22:21:28 | nameStr |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:23:16:23:19 | name |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:24:20:24:23 | name |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:25:29:25:32 | name |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:26:16:26:19 | name |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:27:14:27:17 | name |
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:28:22:28:25 | name |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:35:16:35:22 | nameStr |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:36:20:36:26 | nameStr |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:37:16:37:22 | nameStr |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:38:14:38:20 | nameStr |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:39:22:39:28 | nameStr |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:41:16:41:19 | name |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:42:20:42:23 | name |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:43:16:43:19 | name |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:44:14:44:17 | name |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:45:22:45:25 | name |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:52:16:52:22 | nameStr |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:53:20:53:26 | nameStr |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:54:16:54:22 | nameStr |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:55:14:55:20 | nameStr |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:56:22:56:28 | nameStr |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:58:16:58:19 | name |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:59:20:59:23 | name |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:60:16:60:19 | name |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:61:14:61:17 | name |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:62:22:62:25 | name |
|
||||
| JndiInjection.java:65:42:65:69 | nameStr : String | JndiInjection.java:68:16:68:22 | nameStr |
|
||||
| JndiInjection.java:65:42:65:69 | nameStr : String | JndiInjection.java:69:16:69:22 | nameStr |
|
||||
| JndiInjection.java:72:41:72:68 | nameStr : String | JndiInjection.java:75:16:75:22 | nameStr |
|
||||
| JndiInjection.java:72:41:72:68 | nameStr : String | JndiInjection.java:76:16:76:22 | nameStr |
|
||||
nodes
|
||||
| JndiInjection.java:12:38:12:65 | nameStr : String | semmle.label | nameStr : String |
|
||||
| JndiInjection.java:16:16:16:22 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:17:20:17:26 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:18:29:18:35 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:19:16:19:22 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:20:14:20:20 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:21:22:21:28 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:23:16:23:19 | name | semmle.label | name |
|
||||
| JndiInjection.java:24:20:24:23 | name | semmle.label | name |
|
||||
| JndiInjection.java:25:29:25:32 | name | semmle.label | name |
|
||||
| JndiInjection.java:26:16:26:19 | name | semmle.label | name |
|
||||
| JndiInjection.java:27:14:27:17 | name | semmle.label | name |
|
||||
| JndiInjection.java:28:22:28:25 | name | semmle.label | name |
|
||||
| JndiInjection.java:31:41:31:68 | nameStr : String | semmle.label | nameStr : String |
|
||||
| JndiInjection.java:35:16:35:22 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:36:20:36:26 | 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:16:43:19 | name | semmle.label | name |
|
||||
| JndiInjection.java:44:14:44:17 | name | semmle.label | name |
|
||||
| JndiInjection.java:45:22:45:25 | name | semmle.label | name |
|
||||
| JndiInjection.java:48:42:48:69 | nameStr : String | semmle.label | nameStr : String |
|
||||
| JndiInjection.java:52:16:52:22 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:53:20:53:26 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:54:16:54:22 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:55:14:55:20 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:56:22:56:28 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:58:16:58:19 | name | semmle.label | name |
|
||||
| JndiInjection.java:59:20:59:23 | name | semmle.label | name |
|
||||
| JndiInjection.java:60:16:60:19 | name | semmle.label | name |
|
||||
| JndiInjection.java:61:14:61:17 | name | semmle.label | name |
|
||||
| JndiInjection.java:62:22:62:25 | name | semmle.label | name |
|
||||
| JndiInjection.java:65:42:65:69 | nameStr : String | semmle.label | nameStr : String |
|
||||
| JndiInjection.java:68:16:68:22 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:69:16:69:22 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:72:41:72:68 | nameStr : String | semmle.label | nameStr : String |
|
||||
| JndiInjection.java:75:16:75:22 | nameStr | semmle.label | nameStr |
|
||||
| JndiInjection.java:76:16:76:22 | nameStr | semmle.label | nameStr |
|
||||
#select
|
||||
| JndiInjection.java:16:16:16:22 | nameStr | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:16:16:16:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:17:20:17:26 | nameStr | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:17:20:17:26 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:18:29:18:35 | nameStr | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:18:29:18:35 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:19:16:19:22 | nameStr | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:19:16:19:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:20:14:20:20 | nameStr | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:20:14:20:20 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:21:22:21:28 | nameStr | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:21:22:21:28 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:23:16:23:19 | name | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:23:16:23:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:24:20:24:23 | name | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:24:20:24:23 | name | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:25:29:25:32 | name | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:25:29:25:32 | name | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:26:16:26:19 | name | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:26:16:26:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:27:14:27:17 | name | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:27:14:27:17 | name | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:28:22:28:25 | name | JndiInjection.java:12:38:12:65 | nameStr : String | JndiInjection.java:28:22:28:25 | name | JNDI lookup might include name from $@. | JndiInjection.java:12:38:12:65 | nameStr | this user input |
|
||||
| JndiInjection.java:35:16:35:22 | nameStr | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:35:16:35:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:36:20:36:26 | nameStr | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:36:20:36:26 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:37:16:37:22 | nameStr | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:37:16:37:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:38:14:38:20 | nameStr | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:38:14:38:20 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:39:22:39:28 | nameStr | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:39:22:39:28 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:41:16:41:19 | name | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:41:16:41:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:42:20:42:23 | name | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:42:20:42:23 | name | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:43:16:43:19 | name | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:43:16:43:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:44:14:44:17 | name | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:44:14:44:17 | name | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:45:22:45:25 | name | JndiInjection.java:31:41:31:68 | nameStr : String | JndiInjection.java:45:22:45:25 | name | JNDI lookup might include name from $@. | JndiInjection.java:31:41:31:68 | nameStr | this user input |
|
||||
| JndiInjection.java:52:16:52:22 | nameStr | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:52:16:52:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:53:20:53:26 | nameStr | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:53:20:53:26 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:54:16:54:22 | nameStr | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:54:16:54:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:55:14:55:20 | nameStr | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:55:14:55:20 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:56:22:56:28 | nameStr | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:56:22:56:28 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:58:16:58:19 | name | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:58:16:58:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:59:20:59:23 | name | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:59:20:59:23 | name | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:60:16:60:19 | name | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:60:16:60:19 | name | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:61:14:61:17 | name | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:61:14:61:17 | name | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:62:22:62:25 | name | JndiInjection.java:48:42:48:69 | nameStr : String | JndiInjection.java:62:22:62:25 | name | JNDI lookup might include name from $@. | JndiInjection.java:48:42:48:69 | nameStr | this user input |
|
||||
| JndiInjection.java:68:16:68:22 | nameStr | JndiInjection.java:65:42:65:69 | nameStr : String | JndiInjection.java:68:16:68:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:65:42:65:69 | nameStr | this user input |
|
||||
| JndiInjection.java:69:16:69:22 | nameStr | JndiInjection.java:65:42:65:69 | nameStr : String | JndiInjection.java:69:16:69:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:65:42:65:69 | nameStr | this user input |
|
||||
| JndiInjection.java:75:16:75:22 | nameStr | JndiInjection.java:72:41:72:68 | nameStr : String | JndiInjection.java:75:16:75:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:72:41:72:68 | nameStr | this user input |
|
||||
| JndiInjection.java:76:16:76:22 | nameStr | JndiInjection.java:72:41:72:68 | nameStr : String | JndiInjection.java:76:16:76:22 | nameStr | JNDI lookup might include name from $@. | JndiInjection.java:72:41:72:68 | nameStr | this user input |
|
||||
@@ -0,0 +1,78 @@
|
||||
import javax.naming.CompositeName;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.naming.ldap.InitialLdapContext;
|
||||
|
||||
import org.springframework.jndi.JndiTemplate;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
public class JndiInjection {
|
||||
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);
|
||||
}
|
||||
|
||||
public void testInitialDirContextBad1(@RequestParam String nameStr) throws NamingException {
|
||||
Name name = new CompositeName(nameStr);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public void testSpringJndiTemplateBad1(@RequestParam String nameStr) throws NamingException {
|
||||
JndiTemplate ctx = new JndiTemplate();
|
||||
|
||||
ctx.lookup(nameStr);
|
||||
ctx.lookup(nameStr, null);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE/CWE-074/JndiInjection.ql
|
||||
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/shiro-core-1.5.2
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.apache.shiro.jndi;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
public class JndiTemplate {
|
||||
public Object lookup(final String name) throws NamingException {
|
||||
return new Object();
|
||||
}
|
||||
|
||||
public Object lookup(String name, Class requiredType) throws NamingException {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.springframework.jndi;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
public class JndiTemplate {
|
||||
public Object lookup(final String name) throws NamingException {
|
||||
return new Object();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T lookup(String name, Class<T> requiredType) throws NamingException {
|
||||
return (T) new Object();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.springframework.web.bind.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(value=ElementType.PARAMETER)
|
||||
@Retention(value=RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RequestParam { }
|
||||
Reference in New Issue
Block a user