SolChat Messages Insecure Encryption Method
The SolChat app stored its encryption key and implemented symmetric encryption logic client-side. This means anyone could decrypt every message sent and stored on the Solana blockchain.
Introduction
I saw the following tweet from @aeyakovenko and decided to take a look at this chat app for the Solana ecosystem:
Apart from offering secure audio calls, SolChat's main feature is a text chat. Since the application's website emphasized encryption and security as priorities, I naturally decided to investigate its implementation.
Bug description
I began my analysis by searching through the SolChat web application's JavaScript files for potentially sensitive information. Fortunately, JavaScript map files were also available for download, enabling me to deobfuscate the code for better readability. Using sourcemapper, I downloaded the source code from https://www.solchat.app/static/js/main.xxxxxxxx.js.map.
While there were multiple instances of API keys stored in the code, a particular variable in https://www.solchat.app/static/js/main.xxxxxxxx.js caught my attention:
REACT_APP_API_URL: "c<REDACTED>w"
I identified a single occurrence of it within the deobfuscated JavaScript code:
This strongly suggests a secret key leak used to encrypt and decrypt ALL chat communication. Naturally, using a shared key with this design is inherently insecure and violates best practices, but let's focus on the immediate issue.
Let's attempt to decrypt other users' messages to confirm the vulnerability. We can locate a list of transactions with the contract here.
Let's randomly select a transaction with the SendMessage instruction in the log. For example, this one - https://solscan.io/tx/43k5nkiBhwM5Ln5CQZbXM8fJAUQ49ii4uryv1cqQBBgCpqjkeVhM3c7eJ9prSt4Gt2c3CSYvTT8wcpMfkNTRsnLP
Now we need to extract the instruction data as shown on the screenshot below
It’s in hex format so we need to decode it first:
echo -e $(echo '392822b2bd0a411a58000000553246736447566b5831386e506a544e6c4a6153384e324379314838346e656a4476625776554c4970735637515177586e436f3079744848416b344578344242422f71397a42714f4f7072596c6961312f35557561513d3d' | sed 's/../\\x&/g')
9("??
AXU2FsdGVkX18nPjTNlJaS8N2Cy1H84nejDvbWvULIpsV7QQwXnCo0ytHHAk4Ex4BBB/q9zBqOOprYlia1/5UuaQ==
The part that interests us is marked in bold. It is the base64 encoded ciphertext. Let's jump into a NodeJS console and test if this works.
Here’s the code snippet we will use as a PoC:
var CryptoJS = require("crypto-js");
let dec = CryptoJS.AES.decrypt("<cipher text>", "<encryption key>");
console.log(Buffer.from(dec.toString(CryptoJS.enc.utf8), 'hex').toString());
Success! As you can see on the screenshot, we've successfully retrieved the original message text: ‘it costs -0.000005 SOL for the second message’
Let’s try some other transaction just to confirm - https://solscan.io/tx/3jBRgjw4MaAqUNt7VygsgRmNMhkeKUBfPqXQjDb9m21c3D5WmmoNScXJqqQzVixz9gGvjf2yMqBpCeuRM8ZFp6wZ
We repeat the same process:
The message content was 'Hello' This process can be used to decrypt all messages sent in the application until March 2-3, 2024.
Attack scenarios
The process is straightforward, requiring an attacker with the encryption key to write a simple script. This script would parse all SolChat smart contract transactions (BbWi5gvpp94c7hDfcwqUg1QSnjKSXXhiXKkUUrKsEqYy), identify 'SendMessage' instructions, and extract data to reveal cleartext messages.
A second important problem is that SolChat possesses the private key for all encrypted messages. This creates a potential for unlimited and uncontrolled access – a rogue developer could easily decrypt all communications. Additionally, any future leak of the encryption key would permanently compromise the privacy of every message ever encrypted with it, as they are stored on the blockchain.
Timeline
March 2, 2024: Vulnerability identified and promptly reported to SolChat through multiple channels.
March 3, 2024: SolChat addressed the key leak and client-side code issues. Key was removed from JavaScript, changed and the encryption logic was moved to the server-side. Regarding the design concerns, the team has communicated their intention to move all operations on-chain in version 2 of the product.
March 3, 2024: Publication of this post.
Conclusion
While the immediate issues with the leaked key and client-side code have been addressed, the fundamental design of the application remains problematic. For truly secure communication, apps like this must implement end-to-end encryption. Additionally, storing encrypted private messages on a blockchain creates inherent risks, most notably data permanence and key management. Once a message is sent, it remains on the blockchain forever. If the key leaks, there’s nothing that can be done.
It's crucial to emphasize that SolChat's access to encryption keys allows them to read all your messages. This fundamentally compromises the platform's security. Until this design flaw is addressed in v2, it's strongly advised to avoid sending any confidential information through the platform.
I haven't investigated the audio calls functionality, but a thorough security review of the entire platform is strongly recommended.