Merge pull request #4920 from luchua-bc/java/hash-without-salt

Java: Query to detect hash without salt
This commit is contained in:
Anders Schack-Mulligen
2021-03-25 16:13:26 +01:00
committed by GitHub
9 changed files with 453 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
import java.security.NoSuchAlgorithmException;
public interface HASH {
void init() throws NoSuchAlgorithmException;
int getBlockSize();
void update(byte[] foo, int start, int len) throws NoSuchAlgorithmException;
byte[] digest() throws NoSuchAlgorithmException;
}

View File

@@ -0,0 +1,19 @@
edges
| HashWithoutSalt.java:10:36:10:43 | password : String | HashWithoutSalt.java:10:36:10:54 | getBytes(...) |
| HashWithoutSalt.java:25:13:25:20 | password : String | HashWithoutSalt.java:25:13:25:31 | getBytes(...) |
| HashWithoutSalt.java:93:22:93:29 | password : String | HashWithoutSalt.java:94:17:94:25 | passBytes |
| HashWithoutSalt.java:111:22:111:29 | password : String | HashWithoutSalt.java:112:18:112:26 | passBytes |
nodes
| HashWithoutSalt.java:10:36:10:43 | password : String | semmle.label | password : String |
| HashWithoutSalt.java:10:36:10:54 | getBytes(...) | semmle.label | getBytes(...) |
| HashWithoutSalt.java:25:13:25:20 | password : String | semmle.label | password : String |
| HashWithoutSalt.java:25:13:25:31 | getBytes(...) | semmle.label | getBytes(...) |
| HashWithoutSalt.java:93:22:93:29 | password : String | semmle.label | password : String |
| HashWithoutSalt.java:94:17:94:25 | passBytes | semmle.label | passBytes |
| HashWithoutSalt.java:111:22:111:29 | password : String | semmle.label | password : String |
| HashWithoutSalt.java:112:18:112:26 | passBytes | semmle.label | passBytes |
#select
| 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 : String | The password |
| HashWithoutSalt.java:25:13:25:31 | getBytes(...) | HashWithoutSalt.java:25:13:25:20 | password : String | HashWithoutSalt.java:25:13:25:31 | getBytes(...) | $@ is hashed without a salt. | HashWithoutSalt.java:25:13:25:20 | password : String | The password |
| HashWithoutSalt.java:94:17:94:25 | passBytes | HashWithoutSalt.java:93:22:93:29 | password : String | HashWithoutSalt.java:94:17:94:25 | passBytes | $@ is hashed without a salt. | HashWithoutSalt.java:93:22:93:29 | password : String | The password |
| HashWithoutSalt.java:112:18:112:26 | passBytes | HashWithoutSalt.java:111:22:111:29 | password : String | HashWithoutSalt.java:112:18:112:26 | passBytes | $@ is hashed without a salt. | HashWithoutSalt.java:111:22:111:29 | password : String | The password |

View File

@@ -0,0 +1,147 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class HashWithoutSalt {
// BAD - Hash without a salt.
public String getSHA256Hash(String password) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] messageDigest = md.digest(password.getBytes());
return Base64.getEncoder().encodeToString(messageDigest);
}
// GOOD - Hash with a salt.
public String getSHA256Hash(String password, byte[] salt) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt);
byte[] messageDigest = md.digest(password.getBytes());
return Base64.getEncoder().encodeToString(messageDigest);
}
// BAD - Hash without a salt.
public String getSHA256Hash2(String password) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(password.getBytes());
byte[] messageDigest = md.digest();
return Base64.getEncoder().encodeToString(messageDigest);
}
// GOOD - Hash with a salt.
public String getSHA256Hash2(String password, byte[] salt) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt);
md.update(password.getBytes());
byte[] messageDigest = md.digest();
return Base64.getEncoder().encodeToString(messageDigest);
}
// GOOD - Hash with a salt concatenated with the password.
public String getSHA256Hash3(String password, byte[] salt) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] passBytes = password.getBytes();
byte[] allBytes = new byte[passBytes.length + salt.length];
System.arraycopy(passBytes, 0, allBytes, 0, passBytes.length);
System.arraycopy(salt, 0, allBytes, passBytes.length, salt.length);
byte[] messageDigest = md.digest(allBytes);
byte[] cipherBytes = new byte[32 + salt.length]; // SHA-256 is 32 bytes long
System.arraycopy(messageDigest, 0, cipherBytes, 0, 32);
System.arraycopy(salt, 0, cipherBytes, 32, salt.length);
return Base64.getEncoder().encodeToString(cipherBytes);
}
// GOOD - Hash with a given salt stored somewhere else.
public String getSHA256Hash(String password, String salt) throws NoSuchAlgorithmException {
MessageDigest alg = MessageDigest.getInstance("SHA-256");
String payload = password+":"+salt;
return Base64.getEncoder().encodeToString(alg.digest(payload.getBytes(java.nio.charset.StandardCharsets.UTF_8)));
}
// GOOD - Hash with a given salt stored somewhere else.
public String getSHA256Hash2(String password, String salt, boolean useSalt) throws NoSuchAlgorithmException {
MessageDigest alg = MessageDigest.getInstance("SHA-256");
String payload = useSalt?password+":"+salt:password;
return Base64.getEncoder().encodeToString(alg.digest(payload.getBytes(java.nio.charset.StandardCharsets.UTF_8)));
}
// GOOD - Hash with a salt for a variable named passwordHash, whose value is a hash used as an input for a hashing function.
public String getSHA256Hash3(String passwordHash) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] messageDigest = md.digest(passwordHash.getBytes());
return Base64.getEncoder().encodeToString(messageDigest);
}
public void update(SHA256 sha256, byte[] foo, int start, int len) throws NoSuchAlgorithmException {
sha256.update(foo, start, len);
}
// GOOD - Invoking a wrapper implementation through qualifier with a salt.
public String getWrapperSHA256Hash(String password) throws NoSuchAlgorithmException, ClassNotFoundException, IllegalAccessException, InstantiationException {
SHA256 sha256 = new SHA256();
byte[] salt = getSalt();
byte[] passBytes = password.getBytes();
sha256.update(passBytes, 0, passBytes.length);
sha256.update(salt, 0, salt.length);
return Base64.getEncoder().encodeToString(sha256.digest());
}
// BAD - Invoking a wrapper implementation through qualifier without a salt.
public String getWrapperSHA256Hash2(String password) throws NoSuchAlgorithmException, ClassNotFoundException, IllegalAccessException, InstantiationException {
SHA256 sha256 = new SHA256();
byte[] passBytes = password.getBytes();
sha256.update(passBytes, 0, passBytes.length);
return Base64.getEncoder().encodeToString(sha256.digest());
}
// GOOD - Invoking a wrapper implementation through qualifier and argument with a salt.
public String getWrapperSHA256Hash3(String password) throws NoSuchAlgorithmException {
SHA256 sha256 = new SHA256();
byte[] salt = getSalt();
byte[] passBytes = password.getBytes();
sha256.update(passBytes, 0, passBytes.length);
update(sha256, salt, 0, salt.length);
return Base64.getEncoder().encodeToString(sha256.digest());
}
// BAD - Invoking a wrapper implementation through argument without a salt.
public String getWrapperSHA256Hash4(String password) throws NoSuchAlgorithmException {
SHA256 sha256 = new SHA256();
byte[] passBytes = password.getBytes();
update(sha256, passBytes, 0, passBytes.length);
return Base64.getEncoder().encodeToString(sha256.digest());
}
// GOOD - Invoking a wrapper implementation through argument with a salt.
public String getWrapperSHA256Hash5(String password) throws NoSuchAlgorithmException {
SHA256 sha256 = new SHA256();
byte[] salt = getSalt();
byte[] passBytes = password.getBytes();
update(sha256, passBytes, 0, passBytes.length);
update(sha256, salt, 0, salt.length);
return Base64.getEncoder().encodeToString(sha256.digest());
}
// BAD - Invoke a wrapper implementation with a salt, which is not detected with an interface type variable.
public String getSHA512Hash8(byte[] passphrase) throws NoSuchAlgorithmException, ClassNotFoundException, IllegalAccessException, InstantiationException {
Class c = Class.forName("SHA512");
HASH sha512 = (HASH) (c.newInstance());
byte[] tmp = new byte[4];
byte[] key = new byte[32 * 2];
for (int i = 0; i < 2; i++) {
sha512.init();
tmp[3] = (byte) i;
sha512.update(passphrase, 0, passphrase.length);
System.arraycopy(sha512.digest(), 0, key, i * 32, 32);
}
return Base64.getEncoder().encodeToString(key);
}
public static byte[] getSalt() throws NoSuchAlgorithmException {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[16];
sr.nextBytes(salt);
return salt;
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-759/HashWithoutSalt.ql

View File

@@ -0,0 +1,21 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA256 implements HASH {
MessageDigest md;
public int getBlockSize() {return 32;}
public void init() throws NoSuchAlgorithmException {
try { md = MessageDigest.getInstance("SHA-256"); }
catch (Exception e){
System.err.println(e);
}
}
public void update(byte[] foo, int start, int len) throws NoSuchAlgorithmException {
md.update(foo, start, len);
}
public byte[] digest() throws NoSuchAlgorithmException {
return md.digest();
}
}

View File

@@ -0,0 +1,21 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA512 implements HASH {
MessageDigest md;
public int getBlockSize() {return 32;}
public void init() throws NoSuchAlgorithmException {
try { md = MessageDigest.getInstance("SHA-512"); }
catch (Exception e){
System.err.println(e);
}
}
public void update(byte[] foo, int start, int len) throws NoSuchAlgorithmException {
md.update(foo, start, len);
}
public byte[] digest() throws NoSuchAlgorithmException {
return md.digest();
}
}