mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge pull request #12458 from egregius313/egregius313/promote-insecure-ldap-authentication
Java: Promote LDAP Authentication Query
This commit is contained in:
128
java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll
Normal file
128
java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll
Normal file
@@ -0,0 +1,128 @@
|
||||
/** Provides classes to reason about insecure LDAP authentication. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.frameworks.Networking
|
||||
private import semmle.code.java.frameworks.Jndi
|
||||
|
||||
/**
|
||||
* An expression that represents an insecure (non-SSL, non-private) LDAP URL.
|
||||
*/
|
||||
class InsecureLdapUrl extends Expr {
|
||||
InsecureLdapUrl() {
|
||||
this instanceof InsecureLdapUrlLiteral
|
||||
or
|
||||
// Concatentation of insecure protcol and non-private host:
|
||||
// protocol + host + ...
|
||||
exists(AddExpr e, CompileTimeConstantExpr protocol, Expr rest, Expr host |
|
||||
e = this and
|
||||
protocol = e.getLeftOperand() and
|
||||
rest = e.getRightOperand() and
|
||||
if rest instanceof AddExpr then host = rest.(AddExpr).getLeftOperand() else host = rest
|
||||
|
|
||||
protocol.getStringValue() = "ldap://" and
|
||||
not exists(string hostString | hostString = getHostname(host) |
|
||||
hostString.length() = 0 or // Empty host is loopback address
|
||||
hostString instanceof PrivateHostName
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink representing the construction of a `DirContextEnvironment`.
|
||||
*/
|
||||
class InsecureLdapUrlSink extends DataFlow::Node {
|
||||
InsecureLdapUrlSink() {
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and
|
||||
this.asExpr() = cc.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`.
|
||||
*/
|
||||
predicate isBasicAuthEnv(MethodAccess ma) {
|
||||
hasFieldValueEnv(ma, "java.naming.security.authentication", "simple") or
|
||||
hasFieldNameEnv(ma, "SECURITY_AUTHENTICATION", "simple")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` sets `java.naming.security.protocol` (also known as `Context.SECURITY_PROTOCOL`) to `ssl` in some `Hashtable`.
|
||||
*/
|
||||
predicate isSslEnv(MethodAccess ma) {
|
||||
hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or
|
||||
hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` writes the `java.naming.provider.url` (also known as `Context.PROVIDER_URL`) key of a `Hashtable`.
|
||||
*/
|
||||
predicate isProviderUrlSetter(MethodAccess ma) {
|
||||
ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and
|
||||
ma.getMethod().hasName(["put", "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
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An insecure (non-SSL, non-private) LDAP URL string literal.
|
||||
*/
|
||||
private class InsecureLdapUrlLiteral extends StringLiteral {
|
||||
InsecureLdapUrlLiteral() {
|
||||
// Match connection strings with the LDAP protocol and without private IP addresses to reduce false positives.
|
||||
exists(string s | this.getValue() = s |
|
||||
s.regexpMatch("(?i)ldap://[\\[a-zA-Z0-9].*") and
|
||||
not s.substring(7, s.length()) instanceof PrivateHostName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The class `java.util.Hashtable`. */
|
||||
private class TypeHashtable extends Class {
|
||||
TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") }
|
||||
}
|
||||
|
||||
/** Get the string value of an expression representing a hostname. */
|
||||
private string getHostname(Expr expr) {
|
||||
result = expr.(CompileTimeConstantExpr).getStringValue() or
|
||||
result =
|
||||
expr.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` sets `fieldValue` to `envValue` in some `Hashtable`.
|
||||
*/
|
||||
bindingset[fieldValue, envValue]
|
||||
private predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) {
|
||||
// environment.put("java.naming.security.authentication", "simple")
|
||||
ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and
|
||||
ma.getMethod().hasName(["put", "setProperty"]) and
|
||||
ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = fieldValue and
|
||||
ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` sets attribute name `fieldName` to `envValue` in some `Hashtable`.
|
||||
*/
|
||||
bindingset[fieldName, envValue]
|
||||
private predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envValue) {
|
||||
// environment.put(Context.SECURITY_AUTHENTICATION, "simple")
|
||||
ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and
|
||||
ma.getMethod().hasName(["put", "setProperty"]) and
|
||||
exists(Field f |
|
||||
ma.getArgument(0) = f.getAnAccess() and
|
||||
f.hasName(fieldName) and
|
||||
f.getDeclaringType() instanceof TypeNamingContext
|
||||
) and
|
||||
ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/** Provides dataflow configurations to reason about insecure LDAP authentication. */
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.frameworks.Jndi
|
||||
import semmle.code.java.security.InsecureLdapAuth
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for `ldap://` URL in LDAP authentication.
|
||||
*/
|
||||
module InsecureLdapUrlConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink }
|
||||
|
||||
/** Method call of `env.put()`. */
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(MethodAccess ma |
|
||||
pred.asExpr() = ma.getArgument(1) and
|
||||
isProviderUrlSetter(ma) and
|
||||
succ.asExpr() = ma.getQualifier()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module InsecureLdapUrlFlow = TaintTracking::Global<InsecureLdapUrlConfig>;
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for `simple` basic-authentication in LDAP configuration.
|
||||
*/
|
||||
private module BasicAuthConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) {
|
||||
exists(MethodAccess ma |
|
||||
isBasicAuthEnv(ma) and
|
||||
ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink }
|
||||
}
|
||||
|
||||
module BasicAuthFlow = DataFlow::Global<BasicAuthConfig>;
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for `ssl` configuration in LDAP authentication.
|
||||
*/
|
||||
private module RequiresSslConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) {
|
||||
exists(MethodAccess ma |
|
||||
isSslEnv(ma) and
|
||||
ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink }
|
||||
}
|
||||
|
||||
module RequiresSslFlow = DataFlow::Global<RequiresSslConfig>;
|
||||
51
java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp
Normal file
51
java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp
Normal file
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
When using the Java LDAP API to perform LDAPv3-style extended operations
|
||||
and controls, a context with connection properties including user
|
||||
credentials is started. Transmission of LDAP credentials in cleartext
|
||||
allows remote attackers to obtain sensitive information by sniffing the
|
||||
network.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Use the <code>ldaps://</code> protocol to send credentials through SSL or
|
||||
use SASL authentication.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the following (bad) example, a <code>ldap://</code> URL is used and
|
||||
credentials will be sent in plaintext.
|
||||
</p>
|
||||
<sample src="LdapAuthUseLdap.java"/>
|
||||
|
||||
<p>
|
||||
In the following (good) example, a <code>ldaps://</code> URL is used so
|
||||
credentials will be encrypted with SSL.
|
||||
</p>
|
||||
<sample src="LdapAuthUseLdaps.java"/>
|
||||
|
||||
<p>
|
||||
In the following (good) example, a <code>ldap://</code> URL is used, but
|
||||
SASL authentication is enabled so that the credentials will be encrypted.
|
||||
</p>
|
||||
<sample src="LdapEnableSasl.java"/>
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Oracle:
|
||||
<a href="https://docs.oracle.com/javase/jndi/tutorial/ldap/misc/url.html">LDAP and LDAPS URLs</a>
|
||||
</li>
|
||||
<li>
|
||||
Oracle:
|
||||
<a href="https://docs.oracle.com/javase/tutorial/jndi/ldap/simple.html">Simple authentication</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
25
java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql
Normal file
25
java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @name Insecure LDAP authentication
|
||||
* @description LDAP authentication with credentials sent in cleartext makes sensitive information vulnerable to remote attackers
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 8.8
|
||||
* @precision medium
|
||||
* @id java/insecure-ldap-auth
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-522
|
||||
* external/cwe/cwe-319
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.InsecureLdapAuthQuery
|
||||
import InsecureLdapUrlFlow::PathGraph
|
||||
|
||||
from InsecureLdapUrlFlow::PathNode source, InsecureLdapUrlFlow::PathNode sink
|
||||
where
|
||||
InsecureLdapUrlFlow::flowPath(source, sink) and
|
||||
BasicAuthFlow::flowTo(sink.getNode()) and
|
||||
not RequiresSslFlow::flowTo(sink.getNode())
|
||||
select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(),
|
||||
"LDAP connection string"
|
||||
9
java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdap.java
Normal file
9
java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdap.java
Normal file
@@ -0,0 +1,9 @@
|
||||
String ldapUrl = "ldap://ad.your-server.com:389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
environment.put(Context.SECURITY_PRINCIPAL, ldapUserName);
|
||||
environment.put(Context.SECURITY_CREDENTIALS, password);
|
||||
DirContext dirContext = new InitialDirContext(environment);
|
||||
9
java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdaps.java
Normal file
9
java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdaps.java
Normal file
@@ -0,0 +1,9 @@
|
||||
String ldapUrl = "ldaps://ad.your-server.com:636";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
environment.put(Context.SECURITY_PRINCIPAL, ldapUserName);
|
||||
environment.put(Context.SECURITY_CREDENTIALS, password);
|
||||
DirContext dirContext = new InitialDirContext(environment);
|
||||
9
java/ql/src/Security/CWE/CWE-522/LdapEnableSasl.java
Normal file
9
java/ql/src/Security/CWE/CWE-522/LdapEnableSasl.java
Normal file
@@ -0,0 +1,9 @@
|
||||
String ldapUrl = "ldap://ad.your-server.com:389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI");
|
||||
environment.put(Context.SECURITY_PRINCIPAL, ldapUserName);
|
||||
environment.put(Context.SECURITY_CREDENTIALS, password);
|
||||
DirContext dirContext = new InitialDirContext(environment);
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* The query `java/insecure-ldap-auth` has been promoted from experimental to the main query pack. This query detects transmission of cleartext credentials in LDAP authentication. Insecure LDAP authentication causes sensitive information to be vulnerable to remote attackers. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4854)
|
||||
@@ -1,24 +0,0 @@
|
||||
public class InsecureLdapAuth {
|
||||
/** LDAP authentication */
|
||||
public DirContext ldapAuth(String ldapUserName, String password) {
|
||||
{
|
||||
// BAD: LDAP authentication in cleartext
|
||||
String ldapUrl = "ldap://ad.your-server.com:389";
|
||||
}
|
||||
|
||||
{
|
||||
// GOOD: LDAPS authentication over SSL
|
||||
String ldapUrl = "ldaps://ad.your-server.com:636";
|
||||
}
|
||||
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
environment.put(Context.SECURITY_PRINCIPAL, ldapUserName);
|
||||
environment.put(Context.SECURITY_CREDENTIALS, password);
|
||||
DirContext dirContext = new InitialDirContext(environment);
|
||||
return dirContext;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>When using the Java LDAP API to perform LDAPv3-style extended operations and controls, a context with connection properties including user credentials is started. Transmission of LDAP credentials in cleartext allows remote attackers to obtain sensitive information by sniffing the network.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Use LDAPS to send credentials through SSL or use SASL authentication.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>The following example shows two ways of using LDAP authentication. In the 'BAD' case, the credentials are transmitted in cleartext. In the 'GOOD' case, the credentials are transmitted over SSL.</p>
|
||||
<sample src="InsecureLdapAuth.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Oracle:
|
||||
<a href="https://docs.oracle.com/javase/jndi/tutorial/ldap/misc/url.html">LDAP and LDAPS URLs</a>
|
||||
</li>
|
||||
<li>
|
||||
Oracle:
|
||||
<a href="https://docs.oracle.com/javase/tutorial/jndi/ldap/simple.html">Simple authentication</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,211 +0,0 @@
|
||||
/**
|
||||
* @name Insecure LDAP authentication
|
||||
* @description LDAP authentication with credentials sent in cleartext.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/insecure-ldap-auth
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-522
|
||||
* external/cwe/cwe-319
|
||||
*/
|
||||
|
||||
import java
|
||||
import DataFlow
|
||||
import semmle.code.java.frameworks.Jndi
|
||||
import semmle.code.java.frameworks.Networking
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* Insecure (non-SSL, non-private) LDAP URL string literal.
|
||||
*/
|
||||
class InsecureLdapUrlLiteral extends StringLiteral {
|
||||
InsecureLdapUrlLiteral() {
|
||||
// Match connection strings with the LDAP protocol and without private IP addresses to reduce false positives.
|
||||
exists(string s | this.getValue() = s |
|
||||
s.regexpMatch("(?i)ldap://[\\[a-zA-Z0-9].*") and
|
||||
not s.substring(7, s.length()) instanceof PrivateHostName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The class `java.util.Hashtable`. */
|
||||
class TypeHashtable extends Class {
|
||||
TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a non-private LDAP string is concatenated from both protocol and host.
|
||||
*/
|
||||
predicate concatInsecureLdapString(Expr protocol, Expr host) {
|
||||
protocol.(CompileTimeConstantExpr).getStringValue() = "ldap://" and
|
||||
not exists(string hostString |
|
||||
hostString = host.(CompileTimeConstantExpr).getStringValue() or
|
||||
hostString =
|
||||
host.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue()
|
||||
|
|
||||
hostString.length() = 0 or // Empty host is loopback address
|
||||
hostString instanceof PrivateHostName
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the leftmost operand in a concatenated string */
|
||||
Expr getLeftmostConcatOperand(Expr expr) {
|
||||
if expr instanceof AddExpr
|
||||
then result = getLeftmostConcatOperand(expr.(AddExpr).getLeftOperand())
|
||||
else result = expr
|
||||
}
|
||||
|
||||
/**
|
||||
* String concatenated with `InsecureLdapUrlLiteral`.
|
||||
*/
|
||||
class InsecureLdapUrl extends Expr {
|
||||
InsecureLdapUrl() {
|
||||
this instanceof InsecureLdapUrlLiteral
|
||||
or
|
||||
concatInsecureLdapString(this.(AddExpr).getLeftOperand(),
|
||||
getLeftmostConcatOperand(this.(AddExpr).getRightOperand()))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` writes the `java.naming.provider.url` (also known as `Context.PROVIDER_URL`) key of a `Hashtable`.
|
||||
*/
|
||||
predicate isProviderUrlSetter(MethodAccess ma) {
|
||||
ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and
|
||||
ma.getMethod().hasName(["put", "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
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` sets `fieldValue` to `envValue` in some `Hashtable`.
|
||||
*/
|
||||
bindingset[fieldValue, envValue]
|
||||
predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) {
|
||||
// environment.put("java.naming.security.authentication", "simple")
|
||||
ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and
|
||||
ma.getMethod().hasName(["put", "setProperty"]) and
|
||||
ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = fieldValue and
|
||||
ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` sets attribute name `fieldName` to `envValue` in some `Hashtable`.
|
||||
*/
|
||||
bindingset[fieldName, envValue]
|
||||
predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envValue) {
|
||||
// environment.put(Context.SECURITY_AUTHENTICATION, "simple")
|
||||
ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and
|
||||
ma.getMethod().hasName(["put", "setProperty"]) and
|
||||
exists(Field f |
|
||||
ma.getArgument(0) = f.getAnAccess() and
|
||||
f.hasName(fieldName) and
|
||||
f.getDeclaringType() instanceof TypeNamingContext
|
||||
) and
|
||||
ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`.
|
||||
*/
|
||||
predicate isBasicAuthEnv(MethodAccess ma) {
|
||||
hasFieldValueEnv(ma, "java.naming.security.authentication", "simple") or
|
||||
hasFieldNameEnv(ma, "SECURITY_AUTHENTICATION", "simple")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` sets `java.naming.security.protocol` (also known as `Context.SECURITY_PROTOCOL`) to `ssl` in some `Hashtable`.
|
||||
*/
|
||||
predicate isSslEnv(MethodAccess ma) {
|
||||
hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or
|
||||
hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl")
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for `ldap://` URL in LDAP authentication.
|
||||
*/
|
||||
class InsecureUrlFlowConfig extends TaintTracking::Configuration {
|
||||
InsecureUrlFlowConfig() { this = "InsecureLdapAuth:InsecureUrlFlowConfig" }
|
||||
|
||||
/** Source of `ldap://` connection string. */
|
||||
override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl }
|
||||
|
||||
/** Sink of directory context creation. */
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and
|
||||
sink.asExpr() = cc.getArgument(0)
|
||||
)
|
||||
}
|
||||
|
||||
/** Method call of `env.put()`. */
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(MethodAccess ma |
|
||||
pred.asExpr() = ma.getArgument(1) and
|
||||
isProviderUrlSetter(ma) and
|
||||
succ.asExpr() = ma.getQualifier()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for `simple` basic-authentication in LDAP configuration.
|
||||
*/
|
||||
class BasicAuthFlowConfig extends DataFlow::Configuration {
|
||||
BasicAuthFlowConfig() { this = "InsecureLdapAuth:BasicAuthFlowConfig" }
|
||||
|
||||
/** Source of `simple` configuration. */
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
exists(MethodAccess ma |
|
||||
isBasicAuthEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/** Sink of directory context creation. */
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and
|
||||
sink.asExpr() = cc.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for `ssl` configuration in LDAP authentication.
|
||||
*/
|
||||
class SslFlowConfig extends DataFlow::Configuration {
|
||||
SslFlowConfig() { this = "InsecureLdapAuth:SSLFlowConfig" }
|
||||
|
||||
/** Source of `ssl` configuration. */
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
exists(MethodAccess ma |
|
||||
isSslEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/** Sink of directory context creation. */
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and
|
||||
sink.asExpr() = cc.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureUrlFlowConfig config
|
||||
where
|
||||
config.hasFlowPath(source, sink) and
|
||||
exists(BasicAuthFlowConfig bc | bc.hasFlowTo(sink.getNode())) and
|
||||
not exists(SslFlowConfig sc | sc.hasFlowTo(sink.getNode()))
|
||||
select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(),
|
||||
"LDAP connection string"
|
||||
@@ -1,111 +0,0 @@
|
||||
edges
|
||||
| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment |
|
||||
| InsecureLdapAuth.java:15:3:15:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:20:49:20:59 | environment |
|
||||
| InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String | InsecureLdapAuth.java:15:3:15:13 | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:17:3:17:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:20:49:20:59 | environment |
|
||||
| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment |
|
||||
| InsecureLdapAuth.java:29:3:29:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:34:49:34:59 | environment |
|
||||
| InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String | InsecureLdapAuth.java:29:3:29:13 | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:31:3:31:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:34:49:34:59 | environment |
|
||||
| InsecureLdapAuth.java:45:3:45:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:48:49:48:59 | environment |
|
||||
| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:63:49:63:59 | environment |
|
||||
| InsecureLdapAuth.java:57:3:57:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:63:49:63:59 | environment |
|
||||
| InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String | InsecureLdapAuth.java:57:3:57:13 | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:59:3:59:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment |
|
||||
| InsecureLdapAuth.java:62:3:62:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment |
|
||||
| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:77:49:77:59 | environment |
|
||||
| InsecureLdapAuth.java:72:3:72:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:77:49:77:59 | environment |
|
||||
| InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String | InsecureLdapAuth.java:72:3:72:13 | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:88:3:88:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:91:49:91:59 | environment |
|
||||
| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment |
|
||||
| InsecureLdapAuth.java:100:3:100:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:105:59:105:69 | environment |
|
||||
| InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String | InsecureLdapAuth.java:100:3:100:13 | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:102:3:102:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:105:59:105:69 | environment |
|
||||
| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment |
|
||||
| InsecureLdapAuth.java:115:3:115:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:120:49:120:59 | environment |
|
||||
| InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String | InsecureLdapAuth.java:115:3:115:13 | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:117:3:117:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:120:49:120:59 | environment |
|
||||
| InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | InsecureLdapAuth.java:142:50:142:60 | environment |
|
||||
| InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment |
|
||||
| InsecureLdapAuth.java:140:3:140:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:142:50:142:60 | environment |
|
||||
| InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String | InsecureLdapAuth.java:140:3:140:13 | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment |
|
||||
| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment |
|
||||
| InsecureLdapAuth.java:151:3:151:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:153:50:153:60 | environment |
|
||||
| InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String | InsecureLdapAuth.java:151:3:151:13 | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:153:50:153:60 | environment |
|
||||
nodes
|
||||
| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String |
|
||||
| InsecureLdapAuth.java:15:3:15:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String | semmle.label | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:17:3:17:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | semmle.label | ... + ... : String |
|
||||
| InsecureLdapAuth.java:29:3:29:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String | semmle.label | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:31:3:31:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:45:3:45:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:48:49:48:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | semmle.label | "ldap://ad.your-server.com:636" : String |
|
||||
| InsecureLdapAuth.java:57:3:57:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String | semmle.label | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:59:3:59:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:62:3:62:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String |
|
||||
| InsecureLdapAuth.java:72:3:72:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String | semmle.label | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:77:49:77:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:88:3:88:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:91:49:91:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String |
|
||||
| InsecureLdapAuth.java:100:3:100:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String | semmle.label | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:102:3:102:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String |
|
||||
| InsecureLdapAuth.java:115:3:115:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String | semmle.label | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:117:3:117:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | semmle.label | ... + ... : String |
|
||||
| InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:140:3:140:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String | semmle.label | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | semmle.label | ... + ... : String |
|
||||
| InsecureLdapAuth.java:151:3:151:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String |
|
||||
| InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String | semmle.label | ldapUrl : String |
|
||||
| InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
|
||||
| InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment |
|
||||
| InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment |
|
||||
subpaths
|
||||
#select
|
||||
| InsecureLdapAuth.java:20:49:20:59 | environment | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" | LDAP connection string |
|
||||
| InsecureLdapAuth.java:34:49:34:59 | environment | InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:25:20:25:39 | ... + ... | LDAP connection string |
|
||||
| InsecureLdapAuth.java:105:59:105:69 | environment | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" | LDAP connection string |
|
||||
| InsecureLdapAuth.java:120:49:120:59 | environment | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" | LDAP connection string |
|
||||
| InsecureLdapAuth.java:153:50:153:60 | environment | InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:147:20:147:39 | ... + ... | LDAP connection string |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql
|
||||
@@ -11,13 +11,13 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldap://ad.your-server.com:389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
environment.put(Context.SECURITY_PRINCIPAL, ldapUserName);
|
||||
environment.put(Context.SECURITY_CREDENTIALS, password);
|
||||
DirContext dirContext = new InitialDirContext(environment);
|
||||
DirContext dirContext = new InitialDirContext(environment); // $ hasInsecureLdapAuth
|
||||
}
|
||||
|
||||
// BAD - Test LDAP authentication in cleartext using `DirContext`.
|
||||
@@ -25,13 +25,13 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldap://"+serverName+":389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
environment.put(Context.SECURITY_PRINCIPAL, ldapUserName);
|
||||
environment.put(Context.SECURITY_CREDENTIALS, password);
|
||||
DirContext dirContext = new InitialDirContext(environment);
|
||||
DirContext dirContext = new InitialDirContext(environment); // $ hasInsecureLdapAuth
|
||||
}
|
||||
|
||||
// GOOD - Test LDAP authentication over SSL.
|
||||
@@ -39,7 +39,7 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldaps://ad.your-server.com:636";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
@@ -53,7 +53,7 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldap://ad.your-server.com:636";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
@@ -68,7 +68,7 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldap://ad.your-server.com:389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI");
|
||||
@@ -82,7 +82,7 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldap://localhost:389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
@@ -96,14 +96,14 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldap://ad.your-server.com:389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
environment.put(Context.REFERRAL, "follow");
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
environment.put(Context.SECURITY_PRINCIPAL, ldapUserName);
|
||||
environment.put(Context.SECURITY_CREDENTIALS, password);
|
||||
InitialLdapContext ldapContext = new InitialLdapContext(environment, null);
|
||||
}
|
||||
InitialLdapContext ldapContext = new InitialLdapContext(environment, null); // $ hasInsecureLdapAuth
|
||||
}
|
||||
|
||||
|
||||
// BAD - Test LDAP authentication in cleartext using `DirContext` and string literals.
|
||||
@@ -111,13 +111,13 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldap://ad.your-server.com:389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put("java.naming.factory.initial",
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put("java.naming.provider.url", ldapUrl);
|
||||
environment.put("java.naming.referral", "follow");
|
||||
environment.put("java.naming.security.authentication", "simple");
|
||||
environment.put("java.naming.security.principal", ldapUserName);
|
||||
environment.put("java.naming.security.credentials", password);
|
||||
DirContext dirContext = new InitialDirContext(environment);
|
||||
DirContext dirContext = new InitialDirContext(environment); // $ hasInsecureLdapAuth
|
||||
}
|
||||
|
||||
private void setSSL(Hashtable env) {
|
||||
@@ -136,7 +136,7 @@ public class InsecureLdapAuth {
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
setSSL(environment);
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
setBasicAuth(environment, ldapUserName, password);
|
||||
DirContext dirContext = new InitialLdapContext(environment, null);
|
||||
@@ -147,9 +147,9 @@ public class InsecureLdapAuth {
|
||||
String ldapUrl = "ldap://"+serverName+":389";
|
||||
Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY,
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
"com.sun.jndi.ldap.LdapCtxFactory");
|
||||
environment.put(Context.PROVIDER_URL, ldapUrl);
|
||||
setBasicAuth(environment, ldapUserName, password);
|
||||
DirContext dirContext = new InitialLdapContext(environment, null);
|
||||
DirContext dirContext = new InitialLdapContext(environment, null); // $ hasInsecureLdapAuth
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import java
|
||||
import semmle.code.java.security.InsecureLdapAuthQuery
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class InsecureLdapAuthenticationTest extends InlineExpectationsTest {
|
||||
InsecureLdapAuthenticationTest() { this = "InsecureLdapAuthentication" }
|
||||
|
||||
override string getARelevantTag() { result = "hasInsecureLdapAuth" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasInsecureLdapAuth" and
|
||||
exists(DataFlow::Node sink | InsecureLdapUrlFlow::flowTo(sink) |
|
||||
BasicAuthFlow::flowTo(sink) and
|
||||
not RequiresSslFlow::flowTo(sink) and
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user