Our code audit, and the fixes

Our code audit, and the fixes

Recently someone went through our source code in the open and published a list of the problems they found, and they were right about most of what they wrote. We told everyone we would come back with a full account of every issue and what we did about each one. We also want to say clearly at the start that we did not sit on any of this, because every one of the critical issues was patched and deployed to production within 24 hours of the report going up, and the rest followed shortly after. This post is the detailed version, going through the findings one by one.

Post-quantum encryption

The finding that got the most attention was about our post-quantum encryption. Our site said your messages were protected with post-quantum cryptography using ML-KEM-768, and the code as it shipped did not actually do that, because it generated the keys and uploaded the public half to the server but discarded the secret half before saving it, so the post-quantum layer sat in the project without ever being connected to anything that encrypted your mail. Your messages were still being encrypted the entire time with ECDH P-256 and the Double Ratchet, which is strong and verifiable, but it is not post-quantum. We took the claim down within hours, and then we started the work for real by wiring ML-KEM-768 into our X3DH and Double Ratchet for Aster-to-Aster messages. That work isn’t finished. Some of the post-quantum keys your device uses aren’t signed yet, so their protection still depends on trusting our server, and the iOS app on versions before iOS 26 still sends without the post-quantum layer.

Email password recovery

When you turned on email based password recovery, the client was sending up the encrypted vault and the key that decrypts it together in the same request. We turned the feature off on the server within hours of confirming it, and we contacted every account that had ever enabled it to recommend they rotate their password.

Tor failing open

If Tor failed to start, the request would go out over the normal internet without warning you. It now fails closed, so if Tor is not running the request does not leave your device and you are told why.

Password hashing

Our documentation said we used Argon2id for password hashing, and that was only half right. When you sign in, our servers hash what your device sends with Argon2id. The key that protects your private keys is a separate step: your device derives it from your password with PBKDF2-SHA-256 at 310,000 iterations, not Argon2id. An earlier version of this post said we had moved that step to Argon2id, which was wrong, and our help pages now describe both steps as they run today.

The protocol fixes

Several of the remaining issues were in the messaging protocol. Our Double Ratchet implementation was skipping an authentication step that the specification requires, and that step is in place now so that message headers are authenticated the way they should be. Every message our apps send today includes it, and for compatibility they still accept messages in the older format without it. Signatures on inbound encrypted mail were not being verified, and they are verified now with the result shown to you. Our signed prekey was built on an RSA-4096 key where an elliptic curve key belongs, and moving it to an elliptic curve key corrected that and made registration fast again at the same time. One clarification, since this is the part that gets mixed up the most, is that this only applied to the messaging prekey. Your OpenPGP email keys use standard Ed25519 and Curve25519, and older accounts keep their RSA-4096 keys, so your keys stay portable and work with any standard PGP client you bring.

The app fixes

Another set of issues was in the apps rather than the cryptography. The desktop app had given the part that renders web content the ability to make any network request, and we removed that ability, limited what the renderer is allowed to talk to, and tightened the content security policy so that inline scripts are no longer allowed at all. The tokens that let you switch between accounts had been protected with a key kept in plaintext right beside them, and those are stored properly now. The biometric lock on mobile was only a switch in the interface with no key tied to your fingerprint or your face, and that is handled in the native mobile app, where unlocking is bound to a key held in the device keystore. The check that was meant to block cleartext connections over Tor was matching on a substring instead of the real hostname, and it reads the real hostname now.

All of these are fixed and deployed. You can read the client-side commits in our public repositories under the AGPL.

Share:

Related posts

Hi, we're Aster. Here's what we care about.
Company News

Hi, we're Aster. Here's what we care about.

Aster's mission and the five values we won't trade away: privacy as a right, security that doesn't need an expert, open source apps, no lock-in, and answering to users, not investors. With receipts.

How Aster encrypts your email
Engineering

How Aster encrypts your email

A complete, honest look at how Aster encrypts your email, from key derivation and post-quantum protection to the metadata we store in plaintext and why.

How our decentralized storage works
Engineering

How our decentralized storage works

Your Storage format setting decides how Aster writes your encrypted files. Here's exactly what it does, where your encrypted files end up, and what we can still see, with nothing dressed up.