8 ms·
Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful
- CiPHPerCoder 6y agoTired: {"alg":"none"} Wired: {"alg":"nonE"} The JOSE standards (including JWT) are a gift that keeps on giving to attackers. I designed an alternative format in 2018 called PASETO, which doesn't contain the JOSE foot-guns. (I'm pushing for an IETF RFC this year.) https://paseto.io https://paseto.io EDIT: Also, this affected their Authentication API rather than their JWT library. If you use their JWT library, well, it certainly allows this kind of horrendous misuse... but it is not, per se, vulnerable.
- bflesch 6y agoPaseto is a great project, thank you very much for your contribution!
- ucarion 6y agoWhat IETF WG are you working through?
- CiPHPerCoder 6y agoCFRG
- ucarion 6y agoGood luck! Seems like previous discussions with the mailing list could have gone better, but PASETO seems like promising work!
- tptacek 6y agoAre there links to more recent discussions on CFRG? Did you take any of the critiques from CFRG to heart? I think the v1/v2 local/public points were well-taken.
- CiPHPerCoder 6y agoNothing from 2020 yet. XChaCha has to be prioritized first.
- kyrra 6y ago(googler, opinions are my own) For server-to-server, I continue to prefer PGP to provide my encryption. While Google Payments[0] supports PGP and JWE for encrypting payloads, PGP is well tested and most of the bugs have been worked out. JWS/JWE continues to have implementation bugs (likely due to being too flexible). [0] https://developers.google.com/standard-payments/reference/best-practices https://developers.google.com/standard-payments/reference/be...
- CiPHPerCoder 6y agoPGP isn't great either: https://latacora.micro.blog/2019/07/16/the-pgp-problem.html https://latacora.micro.blog/2019/07/16/the-pgp-problem.html Better options for PGP use cases: - AWS Encryption SDK: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html https://docs.aws.amazon.com/encryption-sdk/latest/developer-... - age https://age-encryption.org https://age-encryption.org - Magic Wormhole https://github.com/warner/magic-wormhole https://github.com/warner/magic-wormhole - NaCl/libsodium (and/or usability wrappers) https://libsodium.gitbook.io/doc/ https://libsodium.gitbook.io/doc/ Better options for JWE use cases: - PASETO: https://paseto.io https://paseto.io - Branca: https://branca.io https://branca.io
- kyrra 6y agoPGP definitely has it's issues. It is a good tool for dealing with files, but yeah, it has it's problems. It looks like Google's security team prefers the use of Tink[0] when having to encrypt things. [0] https://github.com/google/tink https://github.com/google/tink
- CiPHPerCoder 6y agoYes, Tink is acceptable too. :)
- cordite 6y agoTink is great! I wish there were more supported languages. AEAD and AWS KMS to decrypt the key set is perfect for our needs.
- grinich 6y agoI think we're going to use PASETO for some stuff at WorkOS. Thanks for building it. :)
- OatMilkLatte 6y agoI'm going to use PASETO for a personal project I'm working on. If the COVID lockdown ever ends and I have time to work on it. Thanks for building it!
- different_sort 6y agoWhy a new standard than to push for reform to the current standard? Are they just closely protected by greybeards who won't listen to reason? Question comes from a true place of ignorance/curiosity, I definitely understand the need to have unambiguous, easy to implement security tokens without the foot-guns.
- CiPHPerCoder 6y agoSimple answer: Because secure cryptography is backwards-incompatible with insecure cryptography, and the JOSE standards have a lot of legacy cruft that will be hard to jettison. If you're going to put in the work (which I am), you might as well start with a clean slate rather than trying to piecemeal security improvements into their design-by-committee spec.
- different_sort 6y agoThank you for your reply!
- pillfill 6y ago> Why a new standard than to push for reform to the current standard? Or even just an opinionated library with some basic guardrails to prevent bad configurations.
- kelnos 6y agoThat's tempting, but as long as a standard has design flaws, there will be libraries out there that don't prevent bad configurations, and people (through innocent ignorance) will use them and end up in a bad place.
- blattimwind 6y agoThe whole point of modern cryptography is to take all the oodles of rope to hang yourself with and hand it over to the cryptographers, to leave just the absolute minimum amount of rope with the application developers. JWT is the opposite of that. It's essentially a reenactment of the bad parts of 90s crypto, including RSA and NONE ciphers.
- Nursie 6y agoWe use it, but restrict the sig alg to a couple of known-good values, so am hoping this particular vulnerability is not present in our system. We had an infosec guy excitedly tell us that PASETO was the future, and we need to change to it right now. It looked good, and a way to avoid some of the possible JiWY issues in the same way having a TLS implementation that only allowed strong ciphers might. But we have to integrate with so many third party pieces that require JWT it wasn't an option.
- speedgoose 6y agoBefore starting a new project some time ago, I read about the critics to JOSE (JWE) and the alternative PASETO. I decided to use JOSE carefully instead of PASETO because it had an IETF RFC. I think it will be great for PASETO to get a RFC as well. The second point that made me chose JOSE was that PASETO was a bit too mean towards JOSE, and I didn't want drama in my technology choices. But good work! With a RFC PASETO will be my choice for my next projects.
- dwaite 6y ago> I'm pushing for an IETF RFC this year. Are you planning an informational document, or going through the IETF standardization process? Also, the last published draft is two years old this week. Have there been changes since then to the spec? Are implementations generally interoperable?
- CiPHPerCoder 6y agoI'll be sending an email to CFRG, probably next week, with any spec changes. But before I resuscitate PASETO, XChaCha20 needs an RFC. It's pending IRTF kick-off. https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03 https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03
- rvz 6y agoThe gist of this Auth0 authentication API bypass is detailed as follows: > The Authentication API prevented the use of alg: none with a case sensitive filter. This means that simply capitalising any letter e.g. alg: nonE, allowed tokens to be forged. I really don't know what to think of why you need a case-sensitive filter for alg:'none'. The question is that why use and support 'alg:none' in the standard in the first place? As I previously commented, the option to have 'alg: none' should never be used as it is still the biggest footgun in the JOSE specification. Even giving the user a choice of ciphers to use is a recipe for disaster. Thus, JWT is still a cryptographically weak standard and its use is discouraged by many cryptographers. PASETO [0] or Branca [1] are cryptographically stronger alternatives to use over JWT here. [0] https://paseto.io https://paseto.io [1] https://branca.io https://branca.io
- applecrazy 6y ago> the option to have 'alg: none' should never be used I doubt anyone uses this deliberately (edit: except maybe for internal server to server communications?). I agree that having it as an option is a footgun. I still think this is a non-issue on the client/backend, most libraries explicitly make you whitelist token signing algorithms and will throw errors if the token isn't signed with the right algorithm. > Even giving the user a choice of ciphers to use is a recipe for disaster. How so? I'm still learning this stuff, so I'm genuinely curious.
- CiPHPerCoder 6y ago> > Even giving the user a choice of ciphers to use is a recipe for disaster. > How so? I'm still learning this stuff, so I'm genuinely curious. https://paragonie.com/blog/2019/10/against-agility-in-cryptography-protocols https://paragonie.com/blog/2019/10/against-agility-in-crypto... :)
- user5994461 6y agoI really hope you're planning some agility in PASETO otherwise it's de-facto s* protocol that will have to be thrown away within a few years upon the first cryptographic weakness, breaking all applications that dared to adopt it. Fact is, ciphers and protocols evolve over time. In the real world of client-servers (often many clients and many servers), it's not possible to magically upgrade all systems at once to exclusively accept a single same cipher. There's got to be a way to phase-in ciphers gradually across systems and phase-off. Agility is simply a real world constraint to be able to operate software in the real world.
- eximius 6y agoAlways normalize your input?
- JdeBP 6y agoTry: Don't encode your machine-to-machine protocol as human-readable strings, leading to things like declaring machine-readable identifiers to be case-insensitive when only the humans need this, not the machines.
- eximius 6y agoeh, arbitrary protocols, sure. But the web has always been human-readable and I don't want to change that. Therefore, you're gunna get serialized strings.
- twic 6y agoAt some point, that alg parameter gets resolved to an algorithm - an object or enum constant or something. This bug implies that the filtering was done on the string value of the parameter, and not the resolved value. That seems like a schoolboy error.
- user5994461 6y agoIt's much worse than that. There are like 5 options for the algorithm value, none, RS256, HS256, etc... The vulnerabilities implies that they don't verify the value against the very limited list of possible values, which is incredibly stupid.
- user5994461 6y agoMost JWT libraries require to hardcode the expected algorithm when verifying a token, so if your applications are verifying the token provided by Auth0 with a JWT library, they're most likely not vulnerable to this mistake.
- Arnout 6y agoI've encountered issues like this in various systems using JWT at this point. The real problem is that developers blacklist the algorithms they don't want. Instead, the verification code should explicitly whitelist which algorithms you support. More specifically, you can't even rely on using the 'alg' parameter before successful signature verification with any level of authority: after all, it is protected by the signature it declares the algorithm for itself. So even with a whitelist, there is the potential of downgrade attacks. In other words, don't even use a whitelist, use a single specific expected algorithm.
- applecrazy 6y ago> Instead, the verification code should explicitly whitelist which algorithms you support. What libraries are you using? I just looked through the auth code for a project I'm working on (which uses `jsonwebtoken`) and it has an option to whitelist algorithms in the `jwt.verify` method. Edit: removed repeated info
- Arnout 6y agoVarious, been a while since I wrote code using them myself. Often JWT tokens come from sources other than our own and they will have passed through user agent or client land. Don't trust anything in them unless you verified them. edit: good on that library! That's what it should do. Clearly auth0's code did not do that though, it should never have accepted any variant of 'none' in the first place.
- applecrazy 6y agoJust wanted to point out the supreme irony: Auth0 wrote that library.
- Arnout 6y agoHah. They could still improve it by only accepting a single algorithm, rather than a list. edit: though there could be some internal use cases where you want a list, but it's a tradeoff between flexibility and making it easy for people to shoot themselves in the foot.
- gjvnq 6y agoWhat if someone used the correct case but weird Unicode characters? I mean, if "none" = "nonE", is "none" = "none"
- CiPHPerCoder 6y agohttps://github.com/auth0/node-jsonwebtoken/blob/5f10bf9957a2541828501cfecab0310908b2f62f/verify.js#L120-L122 https://github.com/auth0/node-jsonwebtoken/blob/5f10bf9957a2... The end result depends entirely on the behavior of JavaScript's Array.indexOf() implementation.
- user5994461 6y agoGood catch. JWT is unicode out-of-the-box, which is really important to support non english user names and such. If Auth0 is doing any sort of normalization they will definitely be vulnerable to all the normalization bugs from unicode. Would be a great follow up vulnerability.
- theamk 6y agoThe answer to that is we should not be using _any_ case-insensitive strings in protocols. They are fine for human-visible names, but field names and internal enum values should use byte-by-byte comparison. It just makes entire class of vulnerabilities go away.
- deathanatos 6y agoThey are case-sensitive. > The "alg" value is a case-sensitive ASCII string containing a StringOrURI value. This Header Parameter MUST be present and MUST be understood and processed by implementations.
- JdeBP 6y agoBut the protocol says that they are case-insensitive! is not a good response to the assertion that machine-to-machine protocols should not be case-insensitive, which is what theamk said.
- NoInputSignal 6y agoI think this points out that the semantics of trusting the header (which is still a part of the message) at all is flawed and leads to implementations getting it wrong and leaving gaps for attackers to exploit.
- xianb 6y agoIt's fascinating how Auth0 actually had a blog post about finding and fixing a handful of JWT vulnerabilities years ago (one of them is more advanced to exploit than this). Just another example of why you always have to be vigilant and that properly implementing encryption/security is hard https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ https://auth0.com/blog/critical-vulnerabilities-in-json-web-...
- emilibellot 6y agosadddddd
- emilibellot 6y agoddddddddddddd
- userbinator 6y agoI think what's more harmful is the fact that something is case-insensitive. Case insensitive may have some benefits for human-facing stuff, but otherwise the byte-exact comparison you get with case-sensitive semantics is superior.
- thinkshiv 6y agoHi all - Shiv from Auth0. I am the CPO and wanted to share some additional context here. On July 31st 2019, at 5:11 am, we received an email from Insomnia reporting a service vulnerability. By 11:00 pm the same day, we had fixed the issue in production. We analyzed the logs and validated that no one exploited the vulnerability. More details from our CSO here: https://auth0.com/blog/insomnia-security-disclosure/?utm_source=twitter&utm_medium=sc&utm_campaign=insomnia_disclosure https://auth0.com/blog/insomnia-security-disclosure/?utm_sou.... Thanks to Insomnia for reporting the vulnerability and their partnership in coordinated disclosure. We appreciate the continued feedback from the security community-at-large to ensure we are providing the most secure platform for our global customers.
- treve 6y agoWhy did your implementation have a case-sensitive check for a fixed list of algorithms, and why are you blacklisting vs. whitelisting acceptable algorithms? 'Old, stable' codebase or not... this is production code for a security product and seems like something that would be picked up during an audit.
- fulafel 6y agoNot the OP but, the sad truth is that code audits aren't that good at eradicating bugs.
- deleted 6y ago[deleted]
- barnyfried 6y agoHAHAHAHAHAHA HAHAHAHAHAHAHA HAHAHAHAHAHAHA
- joepie91_ 6y agoThere's actually three lessons to be drawn from this incident: 1. Don't use JWT, it's too easy to mess up. 2. If you're trying to fence off some sort of format or API, whitelist things, don't blacklist them. 3. This narrative that "you should use a third-party authentication provider because they're security experts and are much less likely to get it wrong"... well... I think you can see where I'm going with this.
- rgj 6y agoWithout reading the article: any kind of blacklisting is considered harmful in security.
- tinus_hn 6y agoBlacklisting while you should have been whitelisting is harmful. Choose what you allow instead of trying to list what you don’t.