GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • CodeQL documentation
  • CodeQL overview
  • Writing CodeQL queries
  • CodeQL language guides
  • QL language reference
  • CodeQL standard-libraries
  • CodeQL query help
  • CodeQL repository
  • QL publications
  • CodeQL query help for C and C++
  • CodeQL query help for C#
  • CodeQL query help for GitHub Actions
  • CodeQL query help for Go
  • CodeQL query help for Java and Kotlin

This view

  • Original page
  • New address

GeezerVison is showing codeql.github.com — Insecure local authentication — CodeQL query help documentation

Insecure local authentication¶

ID: java/android/insecure-local-authentication
Kind: problem
Security severity: 4.4
Severity: warning
Precision: high
Tags:
   - security
   - external/cwe/cwe-287
Query suites:
   - java-code-scanning.qls
   - java-security-extended.qls
   - java-security-and-quality.qls

Click to see the query in the CodeQL repository

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 use a KeyStore-backed key, it can be bypassed by a privileged malicious application, or by an attacker with physical access using application hooking tools such as Frida.

Recommendation¶

Generate a secure key in the Android KeyStore. Ensure that the onAuthenticationSuccess callback for a biometric prompt uses it in a way that is required for the sensitive parts of the application to function, such as by using it to decrypt sensitive data or credentials.

Example¶

In the following (bad) case, no CryptoObject is required for the biometric prompt to grant access, so it can be bypassed.

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 KeyStore. The application requires this secret key for access, using it to decrypt data.

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¶

  • OWASP Mobile Application Security: Android Local Authentication

  • OWASP Mobile Application Security: Testing Biometric Authentication

  • WithSecure: How Secure is your Android Keystore Authentication?

  • Android Developers: Biometric Authentication

  • Common Weakness Enumeration: CWE-287.

  • © GitHub, Inc.
  • Terms
  • Privacy
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.