Skip to content

Commit 3af8773

Browse files
committed
Add more cases
1 parent 86c04e6 commit 3af8773

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

java/ql/src/experimental/Security/CWE/CWE-759/HashWithoutSalt.ql

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ string getPasswordRegex() { result = "(?i).*pass(wd|word|code|phrase).*" }
3838
/** Finds variables that hold password information judging by their names. */
3939
class PasswordVarExpr extends Expr {
4040
PasswordVarExpr() {
41-
exists(Variable v | this = v.getAnAccess() | v.getName().regexpMatch(getPasswordRegex()))
41+
exists(Variable v | this = v.getAnAccess() |
42+
(
43+
v.getName().toLowerCase().regexpMatch(getPasswordRegex()) and
44+
not v.getName().toLowerCase().matches("%hash%") // Exclude variable names such as `passwordHash` since their values were already hashed
45+
)
46+
)
4247
}
4348
}
4449

@@ -77,17 +82,20 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration {
7782
}
7883

7984
/**
80-
* Holds if a password is concatenated with a salt then hashed together through the call `System.arraycopy(password.getBytes(), ...)`. For example,
85+
* Holds if a password is concatenated with a salt then hashed together through the call `System.arraycopy(password.getBytes(), ...)`, for example,
8186
* `System.arraycopy(password.getBytes(), 0, allBytes, 0, password.getBytes().length);`
8287
* `System.arraycopy(salt, 0, allBytes, password.getBytes().length, salt.length);`
8388
* `byte[] messageDigest = md.digest(allBytes);`
89+
* Or the password is concatenated with a salt as a string.
8490
*/
8591
override predicate isSanitizer(DataFlow::Node node) {
8692
exists(MethodAccess ma |
8793
ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "System") and
8894
ma.getMethod().hasName("arraycopy") and
8995
ma.getArgument(0) = node.asExpr()
90-
)
96+
) // System.arraycopy(password.getBytes(), ...)
97+
or
98+
exists(AddExpr e | node.asExpr() = e.getAnOperand()) // password+salt
9199
}
92100
}
93101

java/ql/test/experimental/query-tests/security/CWE-759/HashWithoutSalt.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ public String getSHA256Hash3(String password, byte[] salt) throws NoSuchAlgorith
5252
return Base64.getEncoder().encodeToString(cipherBytes);
5353
}
5454

55+
// GOOD - Hash with a given salt stored somewhere else.
56+
public String getSHA256Hash(String password, String salt) throws NoSuchAlgorithmException {
57+
return hash(password+salt);
58+
}
59+
60+
// GOOD - Hash with a salt for a variable named passwordHash, whose value is a hash used as an input for a hashing function.
61+
public String getSHA256Hash3(String passwordHash) throws NoSuchAlgorithmException {
62+
MessageDigest md = MessageDigest.getInstance("SHA-256");
63+
byte[] messageDigest = md.digest(passwordHash.getBytes());
64+
return Base64.getEncoder().encodeToString(messageDigest);
65+
}
66+
67+
private String hash(String payload) {
68+
MessageDigest alg = MessageDigest.getInstance("SHA-256");
69+
return Base64.getEncoder().encodeToString(alg.digest(payload.getBytes(java.nio.charset.StandardCharsets.UTF_8)));
70+
}
71+
5572
public static byte[] getSalt() throws NoSuchAlgorithmException {
5673
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
5774
byte[] salt = new byte[16];
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import java.security.MessageDigest;
2+
3+
public class SHA256 {
4+
MessageDigest md;
5+
public int getBlockSize() {return 32;}
6+
public void init() throws Exception {
7+
try { md = MessageDigest.getInstance("SHA-256"); }
8+
catch (Exception e){
9+
System.err.println(e);
10+
}
11+
}
12+
13+
public void update(byte[] foo, int start, int len) throws Exception {
14+
md.update(foo, start, len);
15+
}
16+
17+
public byte[] digest() throws Exception {
18+
return md.digest();
19+
}
20+
}

0 commit comments

Comments
 (0)