Neil Madden, a security engineer, writes about cryptography, OAuth, Java security, and post-quantum cryptography.
HN commenters cite his review of Cloudflare's AI-coded OAuth library and his post on key-driven cryptographic agility.
> It's not "JWT is broken". The cryptography is fine. The tymondesigns/jwt-auth package is fine. The concept of using JWT as your app's session is what's broken.
If only that was true. JWT came with a lot of questionable cryptographic choices. It went hard on fine-grained cryptographic agility like it was 1995 all over again. It started with the wrong suite of outdated ciphers like RSA and no good security requirements and implementation guides, and even the notorious "none" algorithm. The end result is a string of CVEs that affected a wide swath of JWT libraries.
JWT has many other ill-conceived features such as embedded JWK, token-declared URLs and the complex mess that is JWE (which you'll need if you want encryption). This complexity, useless features (the "none" algorithm), together with picking algorithms that are hard to implement correctly[1] and not setting any kind of security requirements made vulnerable libraries spread like wildfire, and introduced at least 5 different classes of vulnerabilities[2].
The craziest thing, is that easiest vulnerability to abuse (the "none" algorithm), is a required by the JWT RFC, you read it too literally:
Of the signature and MAC algorithms specified in JSON Web Algorithms
JWA], only HMAC SHA-256 ("HS256") and "none" MUST be implemented by
conforming JWT implementations.
Now, the RFC writers obviously meant that conforming JWT libraries, should support "none" if explicitly requested, but did not mean that the libraries…
First:
Valid point about the image size. A possible sign for bloat? Bloat is danger.
Second:
C, C++ or Rust are our tools. Everyone prefers another for technical and personal reasons. A religious believe in salvation by the next programming language is not helpful and causing harm. I hope sanitizers for C/C++ improve further - which improved safety a lot. For C++28 or C++3x we can hope for further safety improvements. Which we need.
Most bugs are logic errors. SharePoint is - according to my knowledge - implemented in C#. The CVEs mention deserialization of untrusted data, improper limitation of a pathname to a restricted directory ('path traversal'), improper control of generation of code ('code injection') and so on.
I'm rather careful about people requiring another language and claiming it will fix everything. Reliability needs hard work (design, code, review, testing...more review) even with well selected tools. I guess Microsoft does that. And I guess Microsoft works like the rest of the industry, focus on time-to-market and building a monopoly in every area. That's why we see rapid updates in a lot areas and - worse - enforced updates. And why software is known for it's low quality in comparsion to other industries?
Examples:
GNOME opted to use JavaScript in the hype back in 2010:
* JavaScript reduced compatibility compared to C/C++. * They suffered a lot from memory-leaks. Due to JavaScript. * The run-time modification seems not to be a big…
> It costs:
Not wrong, but given these algorithms are mostly used at setup, how much cost is actually being occurred compared to the entire session? Certainly if your sessions are short-lived then the 'overhead' of PQC/hybrid is higher, but I'd be curious to know the actually byte and energy costs over and above non-PQC/hybrid, i.e., how many bytes/joules for a non-PQC exchange and how many more by adding PQC. E.g.
> Unfortunately, many of the proposed post-quantum cryptographic primitives have significant drawbacks compared to existing mechanisms, in particular producing outputs that are much larger. For signatures, a state of the art classical signature scheme is Ed25519, which produces 64-byte signatures and 32-byte public keys, while for widely-used RSA-2048 the values are around 256 bytes for both. Compare this to the lowest security strength ML-DSA post-quantum signature scheme, which has signatures of 2,420 bytes (i.e., over 2kB!) and public keys that are also over a kB in size (1,312 bytes). For encryption, the equivalent would be comparing X25519 as a KEM (32-byte public keys and ciphertexts) with ML-KEM-512 (800-byte PK, 768-byte ciphertext).
* https://neilmadden.blog/2025/06/20/are-we-overthinking-post-quantum-cryptography/
"The impact of data-heavy, post-quantum TLS 1.3 on the Time-To-Last-Byte of real-world connections" (PDF):
*…
I really like the general ideas behind age, like being composable in shell commands and having a more narrow focus than something like GPG.
My biggest frustration with GPG is that it needs to have keys imported to do anything useful. I greatly prefer just storing the keys in the file system!
Related to that last point, Gentoo uses GPG to verify distfiles sometimes and it ends up creating a lot of "dummy" keyrings and throwing them away to circumvent this limitation of GPG! (I haven't dug too deeply into the code so it's possible that I am wrong here, but this is my current understanding)
My two primary issues with age that have prevented me from using it are that it doesn't use authenticated encryption (see links below) and that there is no way to encrypt/decrypt and make signatures with a single key pair (at least afaik). If I am encrypting files I want to be able to trust the contents of it fully, otherwise it's really not that useful for me personally!
https://github.com/FiloSottile/age/issues/59
https://neilmadden.blog/2019/12/30/a-few-comments-on-age/
Your estimation maybe right, but maybe also there is a point on why it is right: https://neilmadden.blog/2025/06/06/a-look-at-cloudflares-ai-coded-oauth-library/
Maybe because (and I'm quoting that article) it is still lacking in what it should have that you managed to accomplish this task in "few days" instead of "a few weeks, maybe months".
Maybe the bottleneck was not your typing speed, but the [specific knowledge] to build that system. Because if you know something well enough, you can build it way faster, like rebuilding something from scratch, you will be faster as you already know the paths. In which case, my question would be: would not be writing this as fast, or maybe at least more secure and reasonable, if you had the complete knowledge of the system first.
Because contrary to LLMs, humans can actually improve and learn when they do things, and they don't whey they don't do things. Not knowing the code to the full extent is worth the time "gained" by using the LLM to write it?
I think it's very hard to estimate those other aspects of the thing.
While the practice of not updating PBKDF2 iterations is bad, I think with LastPass the problem was more the aggregate of many things, a sort-of death by a million cuts. Because truthfully, the PBKDF2 iterations count issue was relatively unimportant. Some good conjecture about it:
https://neilmadden.blog/2023/01/09/on-pbkdf2-iterations/
Both Bitwarden and LastPass should improve this situation by making the iteration count automatically increase over time. For LastPass though, there are... A lot of concerns. The breach, how it was handled, persistent issues with the security of their browser extension (many, including an RCE at one point) and of course the fact that not everything in the vault is actually encrypted.
KeePass XC or 1password may prove to be better options from a strict security practices standpoint, but from what I've seen I don't suspect Bitwarden has a pattern of bad security practices overall. It does seem like there are opportunities to make it better, though.