Skip to content

Commit e5a703e

Browse files
committed
Revamp the query
1 parent babe744 commit e5a703e

File tree

3 files changed

+190
-31
lines changed

3 files changed

+190
-31
lines changed

java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ predicate hasEnvWithValue(MethodAccess ma, string fieldName, string fieldValue,
110110
/**
111111
* Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`.
112112
*/
113-
predicate isSimpleAuthEnv(MethodAccess ma) {
113+
predicate isBasicAuthEnv(MethodAccess ma) {
114114
hasEnvWithValue(ma, "SECURITY_AUTHENTICATION", "java.naming.security.authentication", "simple")
115115
}
116116

@@ -122,32 +122,103 @@ predicate isSSLEnv(MethodAccess ma) {
122122
}
123123

124124
/**
125-
* A taint-tracking configuration for cleartext credentials in LDAP authentication.
125+
* A taint-tracking configuration for `ldap://` URL in LDAP authentication.
126126
*/
127-
class LdapAuthFlowConfig extends TaintTracking::Configuration {
128-
LdapAuthFlowConfig() { this = "InsecureLdapAuth:LdapAuthFlowConfig" }
127+
class InsecureUrlFlowConfig extends TaintTracking::Configuration {
128+
InsecureUrlFlowConfig() { this = "InsecureLdapAuth:InsecureUrlFlowConfig" }
129129

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

133-
/** Sink of provider URL with simple authentication */
133+
/** Sink of directory context creation. */
134134
override predicate isSink(DataFlow::Node sink) {
135-
exists(MethodAccess pma |
136-
sink.asExpr() = pma.getArgument(1) and
137-
isProviderUrlSetter(pma) and
138-
exists(MethodAccess sma |
139-
sma.getQualifier() = pma.getQualifier().(VarAccess).getVariable().getAnAccess() and
140-
isSimpleAuthEnv(sma)
141-
) and
142-
not exists(MethodAccess sma |
143-
sma.getQualifier() = pma.getQualifier().(VarAccess).getVariable().getAnAccess() and
144-
isSSLEnv(sma)
145-
)
135+
exists(ConstructorCall cc |
136+
cc.getConstructedType().getASupertype*() instanceof TypeDirContext and
137+
sink.asExpr() = cc.getArgument(0)
138+
)
139+
}
140+
141+
/** Method call of `env.put()`. */
142+
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
143+
exists(MethodAccess ma |
144+
pred.asExpr() = ma.getArgument(1) and
145+
isProviderUrlSetter(ma) and
146+
succ.asExpr() = ma.getQualifier()
147+
)
148+
}
149+
}
150+
151+
/**
152+
* A taint-tracking configuration for `simple` basic-authentication in LDAP configuration.
153+
*/
154+
class BasicAuthFlowConfig extends TaintTracking::Configuration {
155+
BasicAuthFlowConfig() { this = "InsecureLdapAuth:BasicAuthFlowConfig" }
156+
157+
/** Source of `simple` configuration. */
158+
override predicate isSource(DataFlow::Node src) {
159+
src.asExpr().(CompileTimeConstantExpr).getStringValue() = "simple"
160+
}
161+
162+
/** Sink of directory context creation. */
163+
override predicate isSink(DataFlow::Node sink) {
164+
exists(ConstructorCall cc |
165+
cc.getConstructedType().getASupertype*() instanceof TypeDirContext and
166+
sink.asExpr() = cc.getArgument(0)
167+
)
168+
}
169+
170+
/** Method call of `env.put()`. */
171+
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
172+
exists(MethodAccess ma |
173+
pred.asExpr() = ma.getArgument(1) and
174+
isBasicAuthEnv(ma) and
175+
succ.asExpr() = ma.getQualifier()
146176
)
147177
}
148178
}
149179

150-
from DataFlow::PathNode source, DataFlow::PathNode sink, LdapAuthFlowConfig config
151-
where config.hasFlowPath(source, sink)
180+
/**
181+
* A taint-tracking configuration for `ssl` configuration in LDAP authentication.
182+
*/
183+
class SSLFlowConfig extends TaintTracking::Configuration {
184+
SSLFlowConfig() { this = "InsecureLdapAuth:SSLFlowConfig" }
185+
186+
/** Source of `ssl` configuration. */
187+
override predicate isSource(DataFlow::Node src) {
188+
src.asExpr().(CompileTimeConstantExpr).getStringValue() = "ssl"
189+
}
190+
191+
/** Sink of directory context creation. */
192+
override predicate isSink(DataFlow::Node sink) {
193+
exists(ConstructorCall cc |
194+
cc.getConstructedType().getASupertype*() instanceof TypeDirContext and
195+
sink.asExpr() = cc.getArgument(0)
196+
)
197+
}
198+
199+
/** Method call of `env.put()`. */
200+
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
201+
exists(MethodAccess ma |
202+
pred.asExpr() = ma.getArgument(1) and
203+
isSSLEnv(ma) and
204+
succ.asExpr() = ma.getQualifier()
205+
)
206+
}
207+
}
208+
209+
from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureUrlFlowConfig config, VarAccess va
210+
where
211+
config.hasFlowPath(source, sink) and
212+
sink.getNode().asExpr() = va and
213+
exists(BasicAuthFlowConfig bc, DataFlow::PathNode source2, DataFlow::PathNode sink2 |
214+
bc.hasFlowPath(source2, sink2) and
215+
source2.getNode().asExpr().(CompileTimeConstantExpr).getStringValue() = "simple" and
216+
sink2.getNode().asExpr() = va
217+
) and
218+
not exists(SSLFlowConfig sc, DataFlow::PathNode source3, DataFlow::PathNode sink3 |
219+
sc.hasFlowPath(source3, sink3) and
220+
source3.getNode().asExpr().(CompileTimeConstantExpr).getStringValue() = "ssl" and
221+
sink3.getNode().asExpr() = va.getVariable().getAnAccess()
222+
)
152223
select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(),
153224
"LDAP connection string"
Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,74 @@
11
edges
2-
| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:15:41:15:47 | ldapUrl |
3-
| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:29:41:29:47 | ldapUrl |
4-
| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:100:41:100:47 | ldapUrl |
5-
| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:115:47:115:53 | ldapUrl |
2+
| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment |
3+
| InsecureLdapAuth.java:17:52:17:59 | "simple" : String | InsecureLdapAuth.java:20:49:20:59 | environment |
4+
| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment |
5+
| InsecureLdapAuth.java:31:52:31:59 | "simple" : String | InsecureLdapAuth.java:34:49:34:59 | environment |
6+
| InsecureLdapAuth.java:45:52:45:59 | "simple" : String | InsecureLdapAuth.java:48:49:48:59 | environment |
7+
| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:63:49:63:59 | environment |
8+
| InsecureLdapAuth.java:59:52:59:59 | "simple" : String | InsecureLdapAuth.java:63:49:63:59 | environment |
9+
| InsecureLdapAuth.java:62:46:62:50 | "ssl" : String | InsecureLdapAuth.java:63:49:63:59 | environment |
10+
| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:77:49:77:59 | environment |
11+
| InsecureLdapAuth.java:88:52:88:59 | "simple" : String | InsecureLdapAuth.java:91:49:91:59 | environment |
12+
| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment |
13+
| InsecureLdapAuth.java:102:52:102:59 | "simple" : String | InsecureLdapAuth.java:105:59:105:69 | environment |
14+
| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment |
15+
| InsecureLdapAuth.java:117:58:117:65 | "simple" : String | InsecureLdapAuth.java:120:49:120:59 | environment |
16+
| InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable |
17+
| InsecureLdapAuth.java:124:38:124:42 | "ssl" : String | InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable |
18+
| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable |
19+
| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable |
20+
| InsecureLdapAuth.java:128:44:128:51 | "simple" : String | InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable |
21+
| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | InsecureLdapAuth.java:142:50:142:60 | environment |
22+
| InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment |
23+
| InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment |
24+
| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment |
25+
| InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:153:50:153:60 | environment |
626
nodes
727
| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String |
8-
| InsecureLdapAuth.java:15:41:15:47 | ldapUrl | semmle.label | ldapUrl |
28+
| InsecureLdapAuth.java:17:52:17:59 | "simple" : String | semmle.label | "simple" : String |
29+
| InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment |
30+
| InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment |
931
| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | semmle.label | ... + ... : String |
10-
| InsecureLdapAuth.java:29:41:29:47 | ldapUrl | semmle.label | ldapUrl |
32+
| InsecureLdapAuth.java:31:52:31:59 | "simple" : String | semmle.label | "simple" : String |
33+
| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment |
34+
| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment |
35+
| InsecureLdapAuth.java:45:52:45:59 | "simple" : String | semmle.label | "simple" : String |
36+
| InsecureLdapAuth.java:48:49:48:59 | environment | semmle.label | environment |
37+
| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | semmle.label | "ldap://ad.your-server.com:636" : String |
38+
| InsecureLdapAuth.java:59:52:59:59 | "simple" : String | semmle.label | "simple" : String |
39+
| InsecureLdapAuth.java:62:46:62:50 | "ssl" : String | semmle.label | "ssl" : String |
40+
| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment |
41+
| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment |
42+
| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment |
43+
| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String |
44+
| InsecureLdapAuth.java:77:49:77:59 | environment | semmle.label | environment |
45+
| InsecureLdapAuth.java:88:52:88:59 | "simple" : String | semmle.label | "simple" : String |
46+
| InsecureLdapAuth.java:91:49:91:59 | environment | semmle.label | environment |
1147
| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String |
12-
| InsecureLdapAuth.java:100:41:100:47 | ldapUrl | semmle.label | ldapUrl |
48+
| InsecureLdapAuth.java:102:52:102:59 | "simple" : String | semmle.label | "simple" : String |
49+
| InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment |
50+
| InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment |
1351
| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String |
14-
| InsecureLdapAuth.java:115:47:115:53 | ldapUrl | semmle.label | ldapUrl |
52+
| InsecureLdapAuth.java:117:58:117:65 | "simple" : String | semmle.label | "simple" : String |
53+
| InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment |
54+
| InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment |
55+
| InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable |
56+
| InsecureLdapAuth.java:124:38:124:42 | "ssl" : String | semmle.label | "ssl" : String |
57+
| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable |
58+
| InsecureLdapAuth.java:128:44:128:51 | "simple" : String | semmle.label | "simple" : String |
59+
| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | semmle.label | ... + ... : String |
60+
| InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
61+
| InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
62+
| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment |
63+
| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment |
64+
| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment |
65+
| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | semmle.label | ... + ... : String |
66+
| InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable |
67+
| InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment |
68+
| InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment |
1569
#select
16-
| 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 |
17-
| 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 |
18-
| 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 |
19-
| 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 |
70+
| 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 |
71+
| 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 |
72+
| 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 |
73+
| 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 |
74+
| 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 |

java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,37 @@ public void testCleartextLdapAuth4(String ldapUserName, String password) {
119119
environment.put("java.naming.security.credentials", password);
120120
DirContext dirContext = new InitialDirContext(environment);
121121
}
122+
123+
private void setSSL(Hashtable env) {
124+
env.put(Context.SECURITY_PROTOCOL, "ssl");
125+
}
126+
127+
private void setBasicAuth(Hashtable env, String ldapUserName, String password) {
128+
env.put(Context.SECURITY_AUTHENTICATION, "simple");
129+
env.put(Context.SECURITY_PRINCIPAL, ldapUserName);
130+
env.put(Context.SECURITY_CREDENTIALS, password);
131+
}
132+
133+
// GOOD - Test LDAP authentication with `ssl` configuration and basic authentication.
134+
public void testCleartextLdapAuth5(String ldapUserName, String password, String serverName) {
135+
String ldapUrl = "ldap://"+serverName+":389";
136+
Hashtable<String, String> environment = new Hashtable<String, String>();
137+
setSSL(environment);
138+
environment.put(Context.INITIAL_CONTEXT_FACTORY,
139+
"com.sun.jndi.ldap.LdapCtxFactory");
140+
environment.put(Context.PROVIDER_URL, ldapUrl);
141+
setBasicAuth(environment, ldapUserName, password);
142+
DirContext dirContext = new InitialLdapContext(environment, null);
143+
}
144+
145+
// BAD - Test LDAP authentication with basic authentication.
146+
public void testCleartextLdapAuth6(String ldapUserName, String password, String serverName) {
147+
String ldapUrl = "ldap://"+serverName+":389";
148+
Hashtable<String, String> environment = new Hashtable<String, String>();
149+
environment.put(Context.INITIAL_CONTEXT_FACTORY,
150+
"com.sun.jndi.ldap.LdapCtxFactory");
151+
environment.put(Context.PROVIDER_URL, ldapUrl);
152+
setBasicAuth(environment, ldapUserName, password);
153+
DirContext dirContext = new InitialLdapContext(environment, null);
154+
}
122155
}

0 commit comments

Comments
 (0)