mirror of
https://github.com/github/codeql.git
synced 2026-03-04 22:56:47 +01:00
Merge pull request #15548 from joefarebrother/android-local-auth-keys
Java: Add query for insecurely generated keys for local authentication.
This commit is contained in:
43
java/ql/src/Security/CWE/CWE-287/AndroidInsecureKeys.qhelp
Normal file
43
java/ql/src/Security/CWE/CWE-287/AndroidInsecureKeys.qhelp
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Biometric authentication, such as fingerprint recognition, can be used alongside cryptographic keys stored in the Android <code>KeyStore</code> to protect sensitive parts of the application. However,
|
||||
when a key generated for this purpose has certain parameters set insecurely, an attacker with physical access can bypass the
|
||||
authentication check using application hooking tools such as Frida.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
When generating a key for use with biometric authentication, ensure that the following parameters of <code>KeyGenParameterSpec.Builder</code> are set:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>setUserAuthenticationRequired</code> should be set to <code>true</code>; otherwise, the key can be used without user authentication.</li>
|
||||
<li><code>setInvalidatedByBiometricEnrollment</code> should be set to <code>true</code> (the default); otherwise, an attacker can use the key by enrolling additional biometrics on the device.</li>
|
||||
<li><code>setUserAuthenticationValidityDurationSeconds</code>, if used, should be set to <code>-1</code>; otherwise, non-biometric (less secure) credentials can be used to access the key. We recommend using <code>setUserAuthenticationParameters</code> instead to explicitly set both the timeout and the types of credentials that may be used.</li>
|
||||
</ul>
|
||||
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>The following example demonstrates a key that is configured with secure paramaters:</p>
|
||||
<sample src="AndroidInsecureKeysGood.java"/>
|
||||
|
||||
<p>In each of the following cases, a parameter is set insecurely:</p>
|
||||
<sample src="AndroidInsecureKeysBad.java"/>
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
WithSecure: <a href="https://labs.withsecure.com/publications/how-secure-is-your-android-keystore-authentication">How Secure is your Android Keystore Authentication?</a>.
|
||||
</li>
|
||||
<li>
|
||||
Android Developers: <a href="https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder">KeyGenParameterSpec.Builder</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
18
java/ql/src/Security/CWE/CWE-287/AndroidInsecureKeys.ql
Normal file
18
java/ql/src/Security/CWE/CWE-287/AndroidInsecureKeys.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @name Insecurely generated keys for local authentication
|
||||
* @description Generation of keys with insecure parameters for local biometric authentication can allow attackers with physical access to bypass authentication checks.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 4.4
|
||||
* @precision medium
|
||||
* @id java/android/insecure-local-key-gen
|
||||
* @tags security
|
||||
* external/cwe/cwe-287
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.AndroidLocalAuthQuery
|
||||
|
||||
from InsecureBiometricKeyParamCall call
|
||||
where usesLocalAuth()
|
||||
select call, "This key is not secure for biometric authentication."
|
||||
47
java/ql/src/Security/CWE/CWE-287/AndroidInsecureKeysBad.java
Normal file
47
java/ql/src/Security/CWE/CWE-287/AndroidInsecureKeysBad.java
Normal file
@@ -0,0 +1,47 @@
|
||||
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)
|
||||
// BAD: User authentication is not required to use this key.
|
||||
.setUserAuthenticationRequired(false)
|
||||
.build();
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(
|
||||
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
|
||||
keyGenerator.init(keyGenParameterSpec);
|
||||
keyGenerator.generateKey();
|
||||
}
|
||||
|
||||
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)
|
||||
// BAD: An attacker can access this key by enrolling additional biometrics.
|
||||
.setInvalidatedByBiometricEnrollment(false)
|
||||
.build();
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(
|
||||
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
|
||||
keyGenerator.init(keyGenParameterSpec);
|
||||
keyGenerator.generateKey();
|
||||
}
|
||||
|
||||
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)
|
||||
// BAD: This key can be accessed using non-biometric credentials.
|
||||
.setUserAuthenticationValidityDurationSeconds(30)
|
||||
.build();
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(
|
||||
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
|
||||
keyGenerator.init(keyGenParameterSpec);
|
||||
keyGenerator.generateKey();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
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)
|
||||
// GOOD: Secure parameters are used to generate a key for biometric authentication.
|
||||
.setUserAuthenticationRequired(true)
|
||||
.setInvalidatedByBiometricEnrollment(true)
|
||||
.setUserAuthenticationParameters(0, KeyProperties.AUTH_BIOMETRIC_STRONG)
|
||||
.build();
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(
|
||||
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
|
||||
keyGenerator.init(keyGenParameterSpec);
|
||||
keyGenerator.generateKey();
|
||||
}
|
||||
Reference in New Issue
Block a user