Skip to content

Commit fc7d340

Browse files
committed
Query to detect hard-coded Azure credentials
1 parent 10e76ff commit fc7d340

19 files changed

+974
-4
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
public class HardcodedAzureCredentials {
2+
private final String clientId = "81734019-15a3-50t8-3253-5abe78abc3a1";
3+
private final String username = "[email protected]";
4+
private final String clientSecret = "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_";
5+
private final String tenantId = "22f367ce-535x-357w-2179-a33517mn166h";
6+
7+
//BAD: hard-coded username/password credentials
8+
public void testHardcodedUsernamePassword(String input) {
9+
UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredentialBuilder()
10+
.clientId(clientId)
11+
.username(username)
12+
.password(clientSecret)
13+
.build();
14+
15+
SecretClient client = new SecretClientBuilder()
16+
.vaultUrl("https://myKeyVault.vault.azure.net")
17+
.credential(usernamePasswordCredential)
18+
.buildClient();
19+
}
20+
21+
//GOOD: username/password credentials stored as environment variables
22+
public void testEnvironmentUsernamePassword(String input) {
23+
UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredentialBuilder()
24+
.clientId(clientId)
25+
.username(System.getenv("myUsername"))
26+
.password(System.getenv("mySuperSecurePass"))
27+
.build();
28+
29+
SecretClient client = new SecretClientBuilder()
30+
.vaultUrl("https://myKeyVault.vault.azure.net")
31+
.credential(usernamePasswordCredential)
32+
.buildClient();
33+
}
34+
35+
//BAD: hard-coded client secret
36+
public void testHardcodedClientSecret(String input) {
37+
ClientSecretCredential defaultCredential = new ClientSecretCredentialBuilder()
38+
.clientId(clientId)
39+
.clientSecret(clientSecret)
40+
.tenantId(tenantId)
41+
.build();
42+
}
43+
44+
//GOOD: client secret stored as environment variables
45+
public void testEnvironmentClientSecret(String input) {
46+
ClientSecretCredential defaultCredential = new ClientSecretCredentialBuilder()
47+
.clientId(clientId)
48+
.clientSecret(System.getenv("myClientSecret"))
49+
.tenantId(tenantId)
50+
.build();
51+
}
52+
}

java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.qhelp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,43 @@
3232
Instead, the user name and password could be supplied through environment variables,
3333
which can be set externally without hard-coding credentials in the source code.
3434
</p>
35+
36+
<p>
37+
The following code example connects to AWS using a hard-coded access key ID and secret key:
38+
</p>
39+
40+
<sample src="HardcodedAWSCredentials.java"/>
41+
42+
<p>
43+
Instead, the access key ID and secret key could be supplied through environment variables,
44+
which can be set externally without hard-coding credentials in the source code.
45+
</p>
46+
47+
<p>
48+
The following code example connects to Azure using a hard-coded user name and password or client secret:
49+
</p>
50+
51+
<sample src="HardcodedAzureCredentials.java"/>
52+
53+
<p>
54+
Instead, the username and password or client secret could be supplied through environment variables,
55+
which can be set externally without hard-coding credentials in the source code.
56+
</p>
3557
</example>
3658

3759
<references>
3860
<li>
3961
OWASP:
4062
<a href="https://www.owasp.org/index.php/Use_of_hard-coded_password">Use of hard-coded password</a>.
4163
</li>
64+
<li>
65+
Microsoft:
66+
<a href="https://docs.microsoft.com/en-us/azure/developer/java/sdk/identity-user-auth#username-password-credential">Azure authentication with user credentials</a>.
67+
</li>
68+
<li>
69+
Amazon:
70+
<a href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html">Working with AWS Credentials</a>.
71+
</li>
4272
</references>
4373

4474
</qhelp>

java/ql/src/Security/CWE/CWE-798/SensitiveApi.qll

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ private predicate javaApiCallablePasswordParam(string s) {
130130
s = "sun.tools.jconsole.ProxyClient;getProxyClient(String, int, String, String);3" or
131131
s = "sun.tools.jconsole.ProxyClient;getProxyClient(String, String, String);2" or
132132
s = "sun.tools.jconsole.ProxyClient;getCacheKey(String, int, String, String);3" or
133-
s = "com.amazonaws.auth.BasicAWSCredentials;BasicAWSCredentials(String, String);1"
133+
s = "com.amazonaws.auth.BasicAWSCredentials;BasicAWSCredentials(String, String);1" or
134+
s = "com.azure.identity.UsernamePasswordCredentialBuilder;password(String);0"
134135
}
135136

136137
/**
@@ -202,7 +203,8 @@ private predicate javaApiCallableUsernameParam(string s) {
202203
s = "sun.tools.jconsole.ProxyClient;getConnectionName(String, String);1" or
203204
s = "sun.tools.jconsole.ProxyClient;getProxyClient(String, int, String, String);2" or
204205
s = "sun.tools.jconsole.ProxyClient;getConnectionName(String, int, String);2" or
205-
s = "com.amazonaws.auth.BasicAWSCredentials;BasicAWSCredentials(String, String);0"
206+
s = "com.amazonaws.auth.BasicAWSCredentials;BasicAWSCredentials(String, String);0" or
207+
s = "com.azure.identity.UsernamePasswordCredentialBuilder;username(String);0"
206208
}
207209

208210
/**
@@ -510,5 +512,7 @@ private predicate otherApiCallableCredentialParam(string s) {
510512
s =
511513
"org.springframework.security.core.userdetails.User;User(String, String, boolean, boolean, boolean, boolean, Collection<? extends GrantedAuthority>);0" or
512514
s =
513-
"org.springframework.security.core.userdetails.User;User(String, String, boolean, boolean, boolean, boolean, Collection<? extends GrantedAuthority>);1"
515+
"org.springframework.security.core.userdetails.User;User(String, String, boolean, boolean, boolean, boolean, Collection<? extends GrantedAuthority>);1" or
516+
s = "com.azure.identity.ClientSecretCredentialBuilder;clientSecret(String);0"
517+
514518
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import com.azure.identity.ClientSecretCredential;
2+
import com.azure.identity.ClientSecretCredentialBuilder;
3+
import com.azure.identity.UsernamePasswordCredential;
4+
import com.azure.identity.UsernamePasswordCredentialBuilder;
5+
import com.azure.security.keyvault.secrets.SecretClient;
6+
import com.azure.security.keyvault.secrets.SecretClientBuilder;
7+
8+
public class HardcodedAzureCredentials {
9+
private final String clientId = "81734019-15a3-50t8-3253-5abe78abc3a1";
10+
private final String username = "[email protected]";
11+
private final String clientSecret = "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_";
12+
private final String tenantId = "22f367ce-535x-357w-2179-a33517mn166h";
13+
14+
//BAD: hard-coded username/password credentials
15+
public void testHardcodedUsernamePassword(String input) {
16+
UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredentialBuilder()
17+
.clientId(clientId)
18+
.username(username)
19+
.password(clientSecret)
20+
.build();
21+
22+
SecretClient client = new SecretClientBuilder()
23+
.vaultUrl("https://myKeyVault.vault.azure.net")
24+
.credential(usernamePasswordCredential)
25+
.buildClient();
26+
}
27+
28+
//GOOD: username/password credentials stored as environment variables
29+
public void testEnvironmentUsernamePassword(String input) {
30+
UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredentialBuilder()
31+
.clientId(clientId)
32+
.username(System.getenv("myUsername"))
33+
.password(System.getenv("mySuperSecurePass"))
34+
.build();
35+
36+
SecretClient client = new SecretClientBuilder()
37+
.vaultUrl("https://myKeyVault.vault.azure.net")
38+
.credential(usernamePasswordCredential)
39+
.buildClient();
40+
}
41+
42+
//BAD: hard-coded client secret
43+
public void testHardcodedClientSecret(String input) {
44+
ClientSecretCredential defaultCredential = new ClientSecretCredentialBuilder()
45+
.clientId(clientId)
46+
.clientSecret(clientSecret)
47+
.tenantId(tenantId)
48+
.build();
49+
}
50+
51+
//GOOD: client secret stored as environment variables
52+
public void testEnvironmentClientSecret(String input) {
53+
ClientSecretCredential defaultCredential = new ClientSecretCredentialBuilder()
54+
.clientId(clientId)
55+
.clientSecret(System.getenv("myClientSecret"))
56+
.tenantId(tenantId)
57+
.build();
58+
}
59+
60+
public static void main(String[] args) {
61+
new HardcodedAzureCredentials().testHardcodedUsernamePassword(args[0]);
62+
new HardcodedAzureCredentials().testEnvironmentUsernamePassword(args[0]);
63+
new HardcodedAzureCredentials().testHardcodedClientSecret(args[0]);
64+
new HardcodedAzureCredentials().testEnvironmentClientSecret(args[0]);
65+
}
66+
}

java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ edges
1010
| FileCredentialTest.java:13:14:13:20 | "admin" : String | FileCredentialTest.java:19:13:19:13 | u : String |
1111
| FileCredentialTest.java:19:13:19:13 | u : String | FileCredentialTest.java:22:38:22:45 | v : String |
1212
| FileCredentialTest.java:22:38:22:45 | v : String | FileCredentialTest.java:23:36:23:36 | v |
13+
| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String |
14+
| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String |
15+
| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String |
16+
| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String |
17+
| HardcodedAzureCredentials.java:10:34:10:67 | "[email protected]" : String | HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String |
18+
| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String |
19+
| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String |
20+
| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String |
21+
| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String |
22+
| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | username |
23+
| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret |
24+
| HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String |
25+
| HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret |
26+
| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String |
27+
| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String |
28+
| HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String |
1329
| Test.java:9:16:9:22 | "admin" : String | Test.java:12:13:12:15 | usr : String |
1430
| Test.java:9:16:9:22 | "admin" : String | Test.java:15:36:15:38 | usr |
1531
| Test.java:9:16:9:22 | "admin" : String | Test.java:17:39:17:41 | usr |
@@ -42,6 +58,24 @@ nodes
4258
| FileCredentialTest.java:23:36:23:36 | v | semmle.label | v |
4359
| HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | semmle.label | "ACCESS_KEY" |
4460
| HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | semmle.label | "SECRET_KEY" |
61+
| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | semmle.label | this <.method> [post update] [clientSecret] : String |
62+
| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | semmle.label | this <.method> [post update] [username] : String |
63+
| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | semmle.label | this <.field> [post update] [username] : String |
64+
| HardcodedAzureCredentials.java:10:34:10:67 | "[email protected]" : String | semmle.label | "[email protected]" : String |
65+
| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | semmle.label | this <.field> [post update] [clientSecret] : String |
66+
| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | semmle.label | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String |
67+
| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | semmle.label | parameter this [clientSecret] : String |
68+
| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | semmle.label | parameter this [username] : String |
69+
| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | semmle.label | this <.field> [username] : String |
70+
| HardcodedAzureCredentials.java:18:13:18:20 | username | semmle.label | username |
71+
| HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | semmle.label | clientSecret |
72+
| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String |
73+
| HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | semmle.label | parameter this [clientSecret] : String |
74+
| HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | semmle.label | clientSecret |
75+
| HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String |
76+
| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String |
77+
| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | semmle.label | new HardcodedAzureCredentials(...) [username] : String |
78+
| HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String |
4579
| Test.java:9:16:9:22 | "admin" : String | semmle.label | "admin" : String |
4680
| Test.java:10:17:10:24 | "123456" : String | semmle.label | "123456" : String |
4781
| Test.java:12:13:12:15 | usr : String | semmle.label | usr : String |
@@ -72,6 +106,9 @@ nodes
72106
| FileCredentialTest.java:18:35:18:41 | "admin" | FileCredentialTest.java:18:35:18:41 | "admin" | FileCredentialTest.java:18:35:18:41 | "admin" | Hard-coded value flows to $@. | FileCredentialTest.java:18:35:18:41 | "admin" | sensitive API call |
73107
| HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | Hard-coded value flows to $@. | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | sensitive API call |
74108
| HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | Hard-coded value flows to $@. | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | sensitive API call |
109+
| HardcodedAzureCredentials.java:10:34:10:67 | "[email protected]" | HardcodedAzureCredentials.java:10:34:10:67 | "[email protected]" : String | HardcodedAzureCredentials.java:18:13:18:20 | username | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:18:13:18:20 | username | sensitive API call |
110+
| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | sensitive API call |
111+
| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | sensitive API call |
75112
| Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:15:36:15:38 | usr | Hard-coded value flows to $@. | Test.java:15:36:15:38 | usr | sensitive API call |
76113
| Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:17:39:17:41 | usr | Hard-coded value flows to $@. | Test.java:17:39:17:41 | usr | sensitive API call |
77114
| Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:18:39:18:41 | usr | Hard-coded value flows to $@. | Test.java:18:39:18:41 | usr | sensitive API call |

0 commit comments

Comments
 (0)