Skip to content

Commit fa6ac06

Browse files
egregius313atorralba
authored andcommitted
Add com.auth0.jwt.algorithm.Algorithm sinks
The HMAC* constructors of the com.auth0.jwt.algorithm.Algorithm class take a secret as a parameter. Therefore, the arguments should be added to be checked for hardcoded credentials.
1 parent 85bf10e commit fa6ac06

File tree

4 files changed

+71
-3
lines changed

4 files changed

+71
-3
lines changed

java/ql/lib/semmle/code/java/security/SensitiveApi.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,5 +490,8 @@ private predicate otherApiCallableCredentialParam(string s) {
490490
"com.microsoft.sqlserver.jdbc.SQLServerDataSource;setPassword(String);0",
491491
"com.microsoft.sqlserver.jdbc.SQLServerDataSource;getConnection(String, String);0",
492492
"com.microsoft.sqlserver.jdbc.SQLServerDataSource;getConnection(String, String);1",
493+
"com.auth0.jwt.algorithms.Algorithm;HMAC256(String);0",
494+
"com.auth0.jwt.algorithms.Algorithm;HMAC384(String);0",
495+
"com.auth0.jwt.algorithms.Algorithm;HMAC512(String);0"
493496
]
494497
}

java/ql/test/experimental/query-tests/security/CWE-321/HardcodedJwtKey.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public String accessTokenBad(String username) {
2222
.withExpiresAt(new Date(new Date().getTime() + ACCESS_EXPIRE_TIME))
2323
.withIssuer(ISSUER)
2424
.withClaim("username", username)
25-
.sign(algorithm);
25+
.sign(algorithm); // $ HardcodedCredentialsApiCall
2626
}
2727

2828
// GOOD: Get secret from system configuration then sign a token
@@ -43,7 +43,7 @@ public boolean verifyTokenBad(String token) {
4343
.withIssuer(ISSUER)
4444
.build();
4545
try {
46-
verifier.verify(token);
46+
verifier.verify(token); // $ HardcodedCredentialsApiCall
4747
return true;
4848
} catch (JWTVerificationException e) {
4949
return false;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import java.util.Date;
2+
import java.util.Properties;
3+
4+
import com.auth0.jwt.JWT;
5+
import com.auth0.jwt.algorithms.Algorithm;
6+
import com.auth0.jwt.exceptions.JWTVerificationException;
7+
import com.auth0.jwt.interfaces.JWTVerifier;
8+
9+
public class HardcodedJwtKey {
10+
// 15 minutes
11+
private static final long ACCESS_EXPIRE_TIME = 1000 * 60 * 15;
12+
13+
private static final String ISSUER = "example_com";
14+
15+
private static final String SECRET = "hardcoded_secret";
16+
17+
// BAD: Get secret from hardcoded string then sign a JWT token
18+
public String accessTokenBad(String username) {
19+
Algorithm algorithm = Algorithm.HMAC256(SECRET); // $ HardcodedCredentialsApiCall
20+
21+
return JWT.create()
22+
.withExpiresAt(new Date(new Date().getTime() + ACCESS_EXPIRE_TIME))
23+
.withIssuer(ISSUER)
24+
.withClaim("username", username)
25+
.sign(algorithm);
26+
}
27+
28+
// GOOD: Get secret from system configuration then sign a token
29+
public String accessTokenGood(String username) {
30+
String tokenSecret = System.getenv("SECRET_KEY");
31+
Algorithm algorithm = Algorithm.HMAC256(tokenSecret);
32+
33+
return JWT.create()
34+
.withExpiresAt(new Date(new Date().getTime() + ACCESS_EXPIRE_TIME))
35+
.withIssuer(ISSUER)
36+
.withClaim("username", username)
37+
.sign(algorithm);
38+
}
39+
40+
// BAD: Get secret from hardcoded string then verify a JWT token
41+
public boolean verifyTokenBad(String token) {
42+
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)) // $ HardcodedCredentialsApiCall
43+
.withIssuer(ISSUER)
44+
.build();
45+
try {
46+
verifier.verify(token);
47+
return true;
48+
} catch (JWTVerificationException e) {
49+
return false;
50+
}
51+
}
52+
53+
// GOOD: Get secret from environment variable then verify a JWT token
54+
public boolean verifyTokenGood(String token) {
55+
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(System.getenv("SECRET_KEY")))
56+
.withIssuer(ISSUER)
57+
.build();
58+
try {
59+
verifier.verify(token);
60+
return true;
61+
} catch (JWTVerificationException e) {
62+
return false;
63+
}
64+
}
65+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/amazon-aws-sdk-1.11.700:${testdir}/../../../../../stubs/azure-sdk-for-java:${testdir}/../../../../../stubs/shiro-core-1.4.0:${testdir}/../../../../../stubs/jsch-0.1.55:${testdir}/../../../../../stubs/ganymed-ssh-2-260:${testdir}/../../../../../stubs/apache-mina-sshd-2.8.0:${testdir}/../../../../../stubs/sshj-0.33.0:${testdir}/../../../../../stubs/j2ssh-1.5.5:${testdir}/../../../../../stubs/trilead-ssh2-212:${testdir}/../../../../../stubs/apache-commons-net-3.8.0:${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/mssql-jdbc-12.2.0
1+
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/amazon-aws-sdk-1.11.700:${testdir}/../../../../../stubs/azure-sdk-for-java:${testdir}/../../../../../stubs/shiro-core-1.4.0:${testdir}/../../../../../stubs/jsch-0.1.55:${testdir}/../../../../../stubs/ganymed-ssh-2-260:${testdir}/../../../../../stubs/apache-mina-sshd-2.8.0:${testdir}/../../../../../stubs/sshj-0.33.0:${testdir}/../../../../../stubs/j2ssh-1.5.5:${testdir}/../../../../../stubs/trilead-ssh2-212:${testdir}/../../../../../stubs/apache-commons-net-3.8.0:${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/mssql-jdbc-12.2.0:${testdir}/../../../../../stubs/auth0-jwt-2.3

0 commit comments

Comments
 (0)