Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Revamp the query
  • Loading branch information
luchua-bc committed Jan 15, 2021
commit e5a703e49c3fe53aeda8e6ecb9d3766df7683124
109 changes: 90 additions & 19 deletions java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ predicate hasEnvWithValue(MethodAccess ma, string fieldName, string fieldValue,
/**
* Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`.
*/
predicate isSimpleAuthEnv(MethodAccess ma) {
predicate isBasicAuthEnv(MethodAccess ma) {
hasEnvWithValue(ma, "SECURITY_AUTHENTICATION", "java.naming.security.authentication", "simple")
}

Expand All @@ -122,32 +122,103 @@ predicate isSSLEnv(MethodAccess ma) {
}

/**
* A taint-tracking configuration for cleartext credentials in LDAP authentication.
* A taint-tracking configuration for `ldap://` URL in LDAP authentication.
*/
class LdapAuthFlowConfig extends TaintTracking::Configuration {
LdapAuthFlowConfig() { this = "InsecureLdapAuth:LdapAuthFlowConfig" }
class InsecureUrlFlowConfig extends TaintTracking::Configuration {
Comment thread
luchua-bc marked this conversation as resolved.
InsecureUrlFlowConfig() { this = "InsecureLdapAuth:InsecureUrlFlowConfig" }

/** Source of non-private LDAP connection string */
/** Source of `ldap://` connection string. */
override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl }

/** Sink of provider URL with simple authentication */
/** Sink of directory context creation. */
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess pma |
sink.asExpr() = pma.getArgument(1) and
isProviderUrlSetter(pma) and
exists(MethodAccess sma |
sma.getQualifier() = pma.getQualifier().(VarAccess).getVariable().getAnAccess() and
isSimpleAuthEnv(sma)
) and
not exists(MethodAccess sma |
sma.getQualifier() = pma.getQualifier().(VarAccess).getVariable().getAnAccess() and
isSSLEnv(sma)
)
exists(ConstructorCall cc |
cc.getConstructedType().getASupertype*() 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 TaintTracking::Configuration {
Comment thread
luchua-bc marked this conversation as resolved.
Outdated
BasicAuthFlowConfig() { this = "InsecureLdapAuth:BasicAuthFlowConfig" }

/** Source of `simple` configuration. */
override predicate isSource(DataFlow::Node src) {
src.asExpr().(CompileTimeConstantExpr).getStringValue() = "simple"
Comment thread
luchua-bc marked this conversation as resolved.
Outdated
}

/** Sink of directory context creation. */
override predicate isSink(DataFlow::Node sink) {
exists(ConstructorCall cc |
cc.getConstructedType().getASupertype*() 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
isBasicAuthEnv(ma) and
succ.asExpr() = ma.getQualifier()
)
}
}

from DataFlow::PathNode source, DataFlow::PathNode sink, LdapAuthFlowConfig config
where config.hasFlowPath(source, sink)
/**
* A taint-tracking configuration for `ssl` configuration in LDAP authentication.
*/
class SSLFlowConfig extends TaintTracking::Configuration {
Comment thread
luchua-bc marked this conversation as resolved.
Outdated
SSLFlowConfig() { this = "InsecureLdapAuth:SSLFlowConfig" }

/** Source of `ssl` configuration. */
override predicate isSource(DataFlow::Node src) {
src.asExpr().(CompileTimeConstantExpr).getStringValue() = "ssl"
Comment thread
luchua-bc marked this conversation as resolved.
Outdated
}

/** Sink of directory context creation. */
override predicate isSink(DataFlow::Node sink) {
exists(ConstructorCall cc |
cc.getConstructedType().getASupertype*() 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
isSSLEnv(ma) and
succ.asExpr() = ma.getQualifier()
)
}
}

from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureUrlFlowConfig config, VarAccess va
Comment thread
luchua-bc marked this conversation as resolved.
Outdated
where
config.hasFlowPath(source, sink) and
sink.getNode().asExpr() = va and
Comment thread
luchua-bc marked this conversation as resolved.
Outdated
exists(BasicAuthFlowConfig bc, DataFlow::PathNode source2, DataFlow::PathNode sink2 |
bc.hasFlowPath(source2, sink2) and
source2.getNode().asExpr().(CompileTimeConstantExpr).getStringValue() = "simple" and
Comment thread
luchua-bc marked this conversation as resolved.
Outdated
sink2.getNode().asExpr() = va
Comment thread
luchua-bc marked this conversation as resolved.
Outdated
) and
not exists(SSLFlowConfig sc, DataFlow::PathNode source3, DataFlow::PathNode sink3 |
sc.hasFlowPath(source3, sink3) and
source3.getNode().asExpr().(CompileTimeConstantExpr).getStringValue() = "ssl" and
sink3.getNode().asExpr() = va.getVariable().getAnAccess()
)
select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(),
"LDAP connection string"
Original file line number Diff line number Diff line change
@@ -1,19 +1,74 @@
edges
| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:15:41:15:47 | ldapUrl |
| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:29:41:29:47 | ldapUrl |
| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:100:41:100:47 | ldapUrl |
| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:115:47:115:53 | ldapUrl |
| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment |
| InsecureLdapAuth.java:17:52:17:59 | "simple" : String | InsecureLdapAuth.java:20:49:20:59 | environment |
| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment |
| InsecureLdapAuth.java:31:52:31:59 | "simple" : String | InsecureLdapAuth.java:34:49:34:59 | environment |
| InsecureLdapAuth.java:45:52:45:59 | "simple" : String | InsecureLdapAuth.java:48:49:48:59 | environment |
| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:63:49:63:59 | environment |
| InsecureLdapAuth.java:59:52:59:59 | "simple" : String | InsecureLdapAuth.java:63:49:63:59 | environment |
| InsecureLdapAuth.java:62:46:62:50 | "ssl" : String | InsecureLdapAuth.java:63:49:63:59 | environment |
| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:77:49:77:59 | environment |
| InsecureLdapAuth.java:88:52:88:59 | "simple" : String | InsecureLdapAuth.java:91:49:91:59 | environment |
| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment |
| InsecureLdapAuth.java:102:52:102:59 | "simple" : String | InsecureLdapAuth.java:105:59:105:69 | environment |
| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment |
| InsecureLdapAuth.java:117:58:117:65 | "simple" : String | 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:124:38:124:42 | "ssl" : String | InsecureLdapAuth.java:124:3:124:5 | env [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:128:44:128:51 | "simple" : String | InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable |
| 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:141:16:141:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment |
| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment |
| 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:41:15:47 | ldapUrl | semmle.label | ldapUrl |
| InsecureLdapAuth.java:17:52:17:59 | "simple" : String | semmle.label | "simple" : String |
| 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:41:29:47 | ldapUrl | semmle.label | ldapUrl |
| InsecureLdapAuth.java:31:52:31:59 | "simple" : String | semmle.label | "simple" : String |
| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment |
| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment |
| InsecureLdapAuth.java:45:52:45:59 | "simple" : String | semmle.label | "simple" : String |
| 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:59:52:59:59 | "simple" : String | semmle.label | "simple" : String |
| InsecureLdapAuth.java:62:46:62:50 | "ssl" : String | semmle.label | "ssl" : String |
| 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:77:49:77:59 | environment | semmle.label | environment |
| InsecureLdapAuth.java:88:52:88:59 | "simple" : String | semmle.label | "simple" : String |
| 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:41:100:47 | ldapUrl | semmle.label | ldapUrl |
| InsecureLdapAuth.java:102:52:102:59 | "simple" : String | semmle.label | "simple" : String |
| 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:47:115:53 | ldapUrl | semmle.label | ldapUrl |
| InsecureLdapAuth.java:117:58:117:65 | "simple" : String | semmle.label | "simple" : String |
| 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:124:38:124:42 | "ssl" : String | semmle.label | "ssl" : String |
| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable |
| InsecureLdapAuth.java:128:44:128:51 | "simple" : String | semmle.label | "simple" : String |
| 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: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: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 |
#select
| InsecureLdapAuth.java:15:41:15:47 | ldapUrl | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:15:41:15:47 | ldapUrl | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" | LDAP connection string |
| InsecureLdapAuth.java:29:41:29:47 | ldapUrl | InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:29:41:29:47 | ldapUrl | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:25:20:25:39 | ... + ... | LDAP connection string |
| InsecureLdapAuth.java:100:41:100:47 | ldapUrl | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:100:41:100:47 | ldapUrl | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" | LDAP connection string |
| InsecureLdapAuth.java:115:47:115:53 | ldapUrl | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:115:47:115:53 | ldapUrl | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" | LDAP connection string |
| 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 |
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,37 @@ public void testCleartextLdapAuth4(String ldapUserName, String password) {
environment.put("java.naming.security.credentials", password);
DirContext dirContext = new InitialDirContext(environment);
}

private void setSSL(Hashtable env) {
env.put(Context.SECURITY_PROTOCOL, "ssl");
}

private void setBasicAuth(Hashtable env, String ldapUserName, String password) {
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, ldapUserName);
env.put(Context.SECURITY_CREDENTIALS, password);
}

// GOOD - Test LDAP authentication with `ssl` configuration and basic authentication.
public void testCleartextLdapAuth5(String ldapUserName, String password, String serverName) {
String ldapUrl = "ldap://"+serverName+":389";
Hashtable<String, String> environment = new Hashtable<String, String>();
setSSL(environment);
environment.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, ldapUrl);
setBasicAuth(environment, ldapUserName, password);
DirContext dirContext = new InitialLdapContext(environment, null);
}

// BAD - Test LDAP authentication with basic authentication.
public void testCleartextLdapAuth6(String ldapUserName, String password, String serverName) {
String ldapUrl = "ldap://"+serverName+":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);
setBasicAuth(environment, ldapUserName, password);
DirContext dirContext = new InitialLdapContext(environment, null);
}
}