RCQ Messenger Duress PIN Flaw Gave Full Access to Real Database on Android

RCQ developers discovered that their duress PIN feature on Android used the same dataKey for both real and decoy accounts, allowing anyone entering the panic code to unlock the entire message history. The original design aimed to present a believable second account but resulted in the decoy PIN acting as a master key rather than a protective boundary. On iOS the implementation was cryptographically separate yet suffered from contact wiping that made the decoy mode look suspiciously empty. After review the team switched both platforms to independent random keys, generated realistic conversation histories, and disabled network features in decoy mode to avoid server-side linkage. Legacy slots created before the fix remain marked as such and require users to set a new decoy PIN. The post-mortem also covers desktop Argon2id vault encryption, notification leakage risks, and why short PINs remain vulnerable to offline brute-force even with strong KDF parameters.

HabrTranslated from Russian

Read at source

Developers of the open-source messenger RCQ published a detailed post-mortem on flaws in their duress PIN implementation. The feature, also known as panic PIN or decoy code, is intended to let users unlock a harmless version of the app when forced to hand over their device.

Both Android and iOS versions encrypt the local message database. The database key, called dataKey, is stored encrypted with a value derived from the user’s PIN using PBKDF2-HMAC-SHA256 with 400 000 rounds plus a platform-protected pepper. Multiple slots exist for the real PIN, the decoy PIN, and a wipe PIN; each slot was supposed to carry its own payload.

On Android the decoy slot originally stored the identical dataKey used by the real account. Hiding the second account was performed only by an in-memory filter, leaving the real .db files untouched on disk. Entering the decoy code therefore decrypted the genuine conversation history, giving the impression of protection while actually exposing everything.

The root cause traced back to an early design decision to make the decoy mode appear as a second legitimate account sharing the same database. Later analysis showed that server-side correlation via push tokens, IP addresses, and device identifiers would immediately link the two accounts anyway, rendering the shared-key approach both dangerous and unnecessary.

The iOS version avoided the shared-key mistake but introduced its own problem: activating decoy mode cleared contacts and groups, producing an obviously empty application that itself became evidence of concealment. Notifications also bypassed the decoy filter on both platforms, potentially revealing real incoming messages.

After the review the team adopted the iOS cryptographic model across platforms. The decoy slot now holds an independent random key that opens only a separate decoy database. This database is populated with locally generated, realistically dated conversations chosen by the user. No real network requests are possible from decoy mode, eliminating server-side linkage. Legacy slots are marked and require manual re-creation of the decoy PIN.

On desktop the Tauri application uses Argon2id (64 MB memory, 3 passes) to derive a key that encrypts a vault containing both account secrets and message history with AES-256-GCM. The web version deliberately offers no PIN protection because any script in the same origin can read localStorage and IndexedDB.

Meridian digestThe week's most consequential security stories, distilled into one briefing.See the digest

More in Vulnerabilities & Exploits

Telegram for Android Patches Voice Call Vulnerability Enabling Code Execution
Yandex Patches Millions of Stations After eMudhra Certificate Keys Compromised
Cisco ASA and FTD Face DoS Vulnerability in SSL VPN Already Exploited in the Wild