-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java: Add query for insecure local authentication #15481
Java: Add query for insecure local authentication #15481
Conversation
QHelp previews: java/ql/src/Security/CWE/CWE-287/AndroidInsecureLocalAuthentication.qhelpInsecure local authenticationBiometric local authentication such as fingerprint recognition can be used to protect sensitive data or actions within an application. However, if this authentication does not use a RecommendationGenerate a secure key in the Android ExampleIn the following (bad) case, no biometricPrompt.authenticate(
cancellationSignal,
executor,
new BiometricPrompt.AuthenticationCallback {
@Override
// BAD: This authentication callback does not make use of a `CryptoObject` from the `result`.
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
grantAccess()
}
}
) In the following (good) case, a secret key is generated in the Android private void generateSecretKey() {
KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(
"MySecretKey",
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build();
KeyGenerator keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
keyGenerator.init(keyGenParameterSpec);
keyGenerator.generateKey();
}
private SecretKey getSecretKey() {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
return ((SecretKey)keyStore.getKey("MySecretKey", null));
}
private Cipher getCipher() {
return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
}
public prompt(byte[] encryptedData) {
Cipher cipher = getCipher();
SecretKey secretKey = getSecretKey();
cipher.init(Cipher.DECRYPT_MODE, secretKey);
biometricPrompt.authenticate(
new BiometricPrompt.CryptoObject(cipher),
cancellationSignal,
executor,
new BiometricPrompt.AuthenticationCallback() {
@Override
// GOOD: This authentication callback uses the result to decrypt some data.
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
Cipher cipher = result.getCryptoObject().getCipher();
byte[] decryptedData = cipher.doFinal(encryptedData);
grantAccessWithData(decryptedData);
}
}
);
} References
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code LGTM. Just a handful of comments/questions. After resolving them, and assuming DCA and MRVA look good, feel free to go ahead with the docs review.
java/ql/lib/semmle/code/java/security/AndroidLocalAuthQuery.qll
Outdated
Show resolved
Hide resolved
<overview> | ||
<p> | ||
Biometric local authentication such as fingerprint recognition can be used to protect sensitive data or actions within an application. | ||
However, if this authentication does not make use of a <code>KeyStore</code>-backed key, it is able to be bypassed by a privileged malicious application or an attacker with physical access. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we specify that the risk we're trying to defend against is application hooking (with e.g. Frida)?
* @description Local authentication that does not make use of a `CryptoObject` can be bypassed. | ||
* @kind problem | ||
* @problem.severity warning | ||
* @security-severity 9.3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should reduce this score. See this CVE for instance, it's the same issue and it has a 6.7 CVSS.
IMHO, I think we could get it even lower. The CVSS vector that makes sense for me is AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
, which has a 4.4 score.
* @security-severity 9.3 | |
* @security-severity 4.4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the 4.4 obtained by taking the average of the base/impact/exploitability metrics?
This page appears to output 6.7 as an overall CVSS score.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied the wrong link 😅 It's 4.4 when you reduce the Integrity and Availability scores to None
(since we're only considering the Confidentiality impact of accessing data protected by biometrics): https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N&version=3.1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Just the usual minor suggestions
java/ql/src/Security/CWE/CWE-287/AndroidInsecureLocalAuthentication.qhelp
Outdated
Show resolved
Hide resolved
java/ql/src/Security/CWE/CWE-287/AndroidInsecureLocalAuthentication.qhelp
Outdated
Show resolved
Hide resolved
java/ql/src/Security/CWE/CWE-287/AndroidInsecureLocalAuthentication.qhelp
Outdated
Show resolved
Hide resolved
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
This query finds instances of local authentication callbacks that don't use a
CryptoObject
.