-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Biometric Plugin Vulnerability
Extract from the recent penetration test report:
The application's biometric authentication was implemented using the capacitor-biometric-auth plugin (com.aparajita.capacitor.biometricauth). This plugin has a flaw in its implementation which allows the biometric check to be bypassed. The plugin does not make use of CryptoObject when determining if the authentication has succeeded. CryptoObject ensures that biometric authentication is not just a standalone step but is required to unlock a cryptographic key. If the device has a Trusted Execution Environment (TEE) or a Secure Enclave, CryptoObject ensures that authentication happens securely and cannot be manipulated by software. Without CryptoObject, an attacker can intercept and replay an authentication success response.
Reference: https://mas.owasp.org/MASWE/MASVS-AUTH/MASWE-0044/
. Summary
- Problem: The
@aparajita/capacitor-biometric-authplugin has a critical vulnerability. Its biometric authentication method returns a simple boolean (true/false) which can be easily spoofed on compromised devices (rooted/jailbroken). - Root Cause: Secure biometric authentication must be linked to a cryptographic operation in a hardware-secure environment (Trusted Execution Environment/Secure Enclave), not just a standalone identity check. Without this, an attacker can intercept and force a success response.
The app asks the OS, "Is this the correct user?" The OS returns true or false. An attacker on a compromised device can intercept this communication and force a true result, bypassing the biometric check entirely.
Capacitor Plugin@aparajita/capacitor-biometric-auth (Vulnerable)
This plugin only verifies identity, without linking it to any secure cryptographic operation.
Android
The call to BiometricPrompt critically omits a CryptoObject. This decouples the biometric authentication from the Android Keystore's hardware-backed security, rendering it a simple check that can be trivially bypassed on rooted devices. A secure implementation would use prompt.authenticate(promptInfo, cryptoObject) (see Android BiometricPrompt.authenticate).
- File:
.../biometricauth/AuthActivity.java - Vulnerable Code:
(Reference: AuthActivity.java#L118)
// The call does not pass a CryptoObject, making the authentication // a simple check that can be spoofed. prompt.authenticate(promptInfo);
Why CryptoObject (or iOS Equivalent) is Necessary but Insufficient
Using a CryptoObject in Android (or a Keychain-protected key in iOS) with an asymmetric key pair (e.g., ECDSA) enhances biometric authentication security by linking it to a cryptographic operation. The private key, stored in the Android Keystore or iOS Secure Enclave, is only accessible after successful biometric validation, preventing bypass attacks (e.g., hooking onAuthenticationSucceeded with tools like Frida). The private key signs a challenge, providing cryptographic proof of authenticity, as only the biometric-protected key can generate a valid signature. This addresses vulnerabilities in non-cryptographic biometric APIs, which can be spoofed by simulating success callbacks.
Signature Verification
Verifying the signature confirms:
- Biometric authentication was successful, requiring the private key.
- An attacker cannot fake success (e.g., via Frida) without the private key.
- The plugin’s response is untampered, ensuring authenticity.
Limitations of Client-Side Verification
Verifying the signature in a Capacitor app’s JavaScript (running in a WebView) is insecure because:
- On compromised devices (e.g., rooted or jailbroken), attackers can manipulate the JavaScript verification logic, bypassing the signature check.
- Without server-side verification, the use of
CryptoObjectis ineffective, as the client-side environment cannot be trusted to validate the signature securely.
For true security, verification must occur on a server backend. Client-side checks with mitigations (e.g., code obfuscation, environment checks) are insufficient against determined attackers.
Proposed High-Security Authentication Flow with Keria
The core idea is to achieve end-to-end security by delegating the final trust decision to a dedicated cloud agent service (KERIA), ensuring the client application cannot be tricked into a false state of authentication.
1. Cryptographic Proof Generation (Client-Side)
The process begins on the client device. A unique secp256k1 asymmetric key pair is generated locally. The private key is stored directly within the hardware-backed Secure Enclave (iOS) or Keystore (Android), where it is protected by the device's biometric sensors. This key can never be extracted or used without a successful biometric authentication.
To prove the user's presence, the application initiates a challenge-response flow. It uses the biometrically-protected private key to generate a digital signature over a unique challenge. This signature serves as irrefutable cryptographic proof that the legitimate user, and only the legitimate user, has just authenticated on that specific device.
2. Backend Verification (Server-Side)
This cryptographic proof is then sent to the backend service (KERIA). The backend's critical role is to perform verification in a secure, controlled environment, immune to any potential client-side manipulation.
The backend maintains a trusted registry of authorized public keys for each user identity. Upon receiving the signature, it verifies it against the corresponding secp256k1 public key. Because KERIA is designed with cryptographic agility, it can natively handle the same secp256k1 cryptography used by the client, ensuring seamless validation.
For the highest level of security and auditability, this verification could be structured as a KERI interaction event (ixn). Submitting the signature as a formal event would create a permanent, cryptographically-chained record in the user's Key Event Log (KEL). While this provides an unparalleled audit trail, it also causes the KEL to grow with each authentication/confirmation. This may be unnecessary for simple login or confirmation actions, but would be essential in situations that require the highest security, where it is crucial to maintain an unalterable record that attributes every action to a specific user.
Implementation and Next Steps
The viability of this solution depends on a supported interaction protocol within the KERIA agent. It may be necessary to extend KERIA’s current functionality to support this mobile-centric authentication flow. As KERI is a community-driven standard, this process would require discussion and formal approval.
Therefore, the immediate next step is to present this architecture to the KERI community by opening an issue in the official Github repository to clarify the implementation path.
Keria repository: https://github.com/WebOfTrust/keria/issues