version: SonarQube 9.9 Datacenter Edition
I tried to understand what SonarQube can find, and can not find, in terms of hardcoded credentials, based on what I see in our real-life code, most of the time with rule findsecbugs:HARD_CODE_PASSWORD.
I spotted 3 main rules that should do the job: S6473, S2053 and S2068. From my understanding
- S6473 attempts to find all hardcoded credentials based on the API method.
- S2053 attempts to find hardcoded material for cryptography.
- S2068 attempts to simply find everything that is named “password” or whatever is configured.
With my sample code S6473 is doing its job.
I have 1 suggestion: it could also try to find usages of javax.mail.PasswordAuthentication similarly to it finding java.net.PasswordAuthentication:
java.net.PasswordAuthentication authentication = new java.net.PasswordAuthentication("user", "hello1!".toCharArray()); // detected by java:S6437
javax.mail.PasswordAuthentication authentication2 = new javax.mail.PasswordAuthentication("user","hello1!"); // not detected by java:S6437
For rule S2053 I identified something strange:
byte[] defaultSalt = "salt".getBytes();
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(defaultSalt, 20)); // detected by java:S2053
byte[] defaultSalt = { 's', 'a', 'l', 't' };
Cipher pbeCipher2 = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher2.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(defaultSalt, 20)); // not detected by java:S2053
The salt in the 2nd case is as hardcoded as the one in the first case, but gets not detected.
For S2068, would it make sense adding some more credentialWords to the default config ? I am thinking about:
- mail.password (used by Java Mail)
- javax.net.ssl.keyStorePassword (Java Keystore)
- javax.net.ssl.trustStorePassword (Java Truststore)
I know that you can do this on your own, but these properties are very common and not that different to the already present java.naming.security.credentials.
One last thing: Is there any chance that you provide something to not only detect variable names, but also the calling of methods, like
obj.setPassword("hello1!");
obj.password("hello1!");
setProxyPassword("hello1!");
proxyPassword("hello1!");
It would make sense to be able to configure that similarly to the credentialWords of S2068. I will definitely look into creating an own rule that mixes the features of S6437 and S2068.