Skip to content

Commit b9809b0

Browse files
committed
Update the query to work with wrapper classes
1 parent 048167d commit b9809b0

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,15 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration {
8989
ma.getArgument(0) = node.asExpr() and // Detect wrapper methods that invoke `md.update(salt)`
9090
ma != mua and
9191
(
92+
ma.getQualifier().getType() instanceof Interface
93+
or
9294
mua.getQualifier().(VarAccess).getVariable().getAnAccess() = ma.getQualifier()
9395
or
9496
mua.getAnArgument().(VarAccess).getVariable().getAnAccess() = ma.getQualifier()
9597
or
9698
mua.getQualifier().(VarAccess).getVariable().getAnAccess() = ma.getAnArgument()
9799
or
98-
mua.getAnArgument().(VarAccess).getVariable().getAnAccess() = ma.getAnArgument()
100+
mua.getArgument(0).(VarAccess).getVariable().getAnAccess() = ma.getAnArgument()
99101
) and
100102
isMDUpdateCall(mua.getMethod())
101103
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import java.security.NoSuchAlgorithmException;
2+
3+
public interface HASH {
4+
void init() throws NoSuchAlgorithmException;
5+
6+
int getBlockSize();
7+
8+
void update(byte[] foo, int start, int len) throws NoSuchAlgorithmException;
9+
10+
byte[] digest() throws NoSuchAlgorithmException;
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
edges
22
| HashWithoutSalt.java:10:36:10:43 | password : String | HashWithoutSalt.java:10:36:10:54 | getBytes(...) |
33
| HashWithoutSalt.java:17:13:17:20 | password : String | HashWithoutSalt.java:17:13:17:31 | getBytes(...) |
4+
| HashWithoutSalt.java:98:22:98:29 | password : String | HashWithoutSalt.java:99:17:99:25 | passBytes : byte[] |
5+
| HashWithoutSalt.java:99:17:99:25 | passBytes : byte[] | SHA256.java:14:22:14:31 | foo : byte[] |
6+
| SHA256.java:14:22:14:31 | foo : byte[] | SHA256.java:15:15:15:17 | foo |
47
nodes
58
| HashWithoutSalt.java:10:36:10:43 | password : String | semmle.label | password : String |
69
| HashWithoutSalt.java:10:36:10:54 | getBytes(...) | semmle.label | getBytes(...) |
710
| HashWithoutSalt.java:17:13:17:20 | password : String | semmle.label | password : String |
811
| HashWithoutSalt.java:17:13:17:31 | getBytes(...) | semmle.label | getBytes(...) |
12+
| HashWithoutSalt.java:98:22:98:29 | password : String | semmle.label | password : String |
13+
| HashWithoutSalt.java:99:17:99:25 | passBytes : byte[] | semmle.label | passBytes : byte[] |
14+
| SHA256.java:14:22:14:31 | foo : byte[] | semmle.label | foo : byte[] |
15+
| SHA256.java:15:15:15:17 | foo | semmle.label | foo |
916
#select
1017
| HashWithoutSalt.java:10:36:10:54 | getBytes(...) | HashWithoutSalt.java:10:36:10:43 | password : String | HashWithoutSalt.java:10:36:10:54 | getBytes(...) | $@ is hashed without a salt. | HashWithoutSalt.java:10:36:10:43 | password | The password |
1118
| HashWithoutSalt.java:17:13:17:31 | getBytes(...) | HashWithoutSalt.java:17:13:17:20 | password : String | HashWithoutSalt.java:17:13:17:31 | getBytes(...) | $@ is hashed without a salt. | HashWithoutSalt.java:17:13:17:20 | password | The password |
19+
| SHA256.java:15:15:15:17 | foo | HashWithoutSalt.java:98:22:98:29 | password : String | SHA256.java:15:15:15:17 | foo | $@ is hashed without a salt. | HashWithoutSalt.java:98:22:98:29 | password | The password |

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,22 @@ public String getSHA256Hash6(String password) throws NoSuchAlgorithmException {
100100
return Base64.getEncoder().encodeToString(sha256.digest());
101101
}
102102

103+
// GOOD - Invoke a wrapper implementation with a salt, which is only detectable when a class type is declared (not interface).
104+
public String getSHA256Hash7(byte[] passphrase) throws NoSuchAlgorithmException, ClassNotFoundException, IllegalAccessException, InstantiationException {
105+
Class c = Class.forName("SHA256");
106+
HASH sha256 = (HASH) (c.newInstance());
107+
byte[] tmp = new byte[4];
108+
byte[] key = new byte[32 * 2];
109+
for (int i = 0; i < 2; i++) {
110+
sha256.init();
111+
tmp[3] = (byte) i;
112+
sha256.update(tmp, 0, tmp.length);
113+
sha256.update(passphrase, 0, passphrase.length);
114+
System.arraycopy(sha256.digest(), 0, key, i * 32, 32);
115+
}
116+
return Base64.getEncoder().encodeToString(key);
117+
}
118+
103119
private String hash(String payload) throws NoSuchAlgorithmException {
104120
MessageDigest alg = MessageDigest.getInstance("SHA-256");
105121
return Base64.getEncoder().encodeToString(alg.digest(payload.getBytes(java.nio.charset.StandardCharsets.UTF_8)));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import java.security.MessageDigest;
22
import java.security.NoSuchAlgorithmException;
33

4-
public class SHA256 {
4+
public class SHA256 implements HASH {
55
MessageDigest md;
66
public int getBlockSize() {return 32;}
77
public void init() throws NoSuchAlgorithmException {

0 commit comments

Comments
 (0)