Live data from Hacker News

Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

insomniasec.com

71–80 of 97 posts

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#72
post #66

Earlier quoted context omitted.

Hm, I think I prefer branca from a quick look (simpler is better). I'm a little worried that both seem to hide away datestamp/validity though. Branca notes checking the timestamp as optional - I couldn't tell what paseto does by default - other than a reference to a timestamp in the implentor's readme (and then only as an example parameter to the php code). Paseto does helpfully state that there's no replay protectio…

PASETO has the same "claims" as JWT, except they're ISO 8601 timestamps rather than integers (UNIX timestamps). They're not required (as they weren't in JWT). If you want to use them, use them. The parser will validate them if you want it to. https://github.com/paragonie/paseto/blob/master/src/Rules/No... https://github.com/paragonie/paseto/tree/master/docs/02-PHP-...

Thanks for the pointers - I'd looked at that, I think, but missed the add-rule bit.

But to be clear, it's easy to set up the validating service so that it accepts a token with expired timestamp as valid - it's the default to not check the timestamp if present?

A token without timestamp will never be valid if a rule for checking timestamp is added in the parser?

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#73
post #72

Earlier quoted context omitted.

PASETO has the same "claims" as JWT, except they're ISO 8601 timestamps rather than integers (UNIX timestamps). They're not required (as they weren't in JWT). If you want to use them, use them. The parser will validate them if you want it to. https://github.com/paragonie/paseto/blob/master/src/Rules/No... https://github.com/paragonie/paseto/tree/master/docs/02-PHP-...

Thanks for the pointers - I'd looked at that, I think, but missed the add-rule bit. But to be clear, it's easy to set up the validating service so that it accepts a token with expired timestamp as valid - it's the default to not check the timestamp if present? A token without timestamp will never be valid if a rule for checking timestamp is added in the parser?

The default is to not enforce any rules beyond the cryptographic signatures.

If you need any other validations, it's entirely up to you to specify what those are.

You might care about checking `exp`, but I might instead care about `iat` with a hard-coded token lifetime.

PASETO supports whatever zany business logic developers need, but doesn't enforce anything by default.

But once you add a rule to your parser, it will fail-closed on those rules.

> A token without timestamp will never be valid if a rule for checking timestamp is added in the parser?

Correct.

If your parser is set to check timestamps and one is invalid or omitted, it throws an exception.

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#74
post #62

Tired: {"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 EDIT: Also, this affected their Authentication API rather than their JWT library. If you use their JWT library, well, it certainly allows…

> 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?

I'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

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#75

Earlier quoted context omitted.

> > 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-crypto... :)

I 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 excl…

> I 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.

Instead of cipher agility, PASETO uses versioned protocols.

My DEFCON Crypto & Privacy Village talk (slides and YouTube video at https://paseto.io for the curious) covered this distinction in detail.

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#76

Hi 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_s…

Why 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.

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#77
post #67
post #12

What if someone used the correct case but weird Unicode characters? I mean, if "none" = "nonE", is "none" = "none"

The 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.

They 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.

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#78
post #8

I'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 sig…

  fn verify_jwt(
    // The input from the network/user; the JWT we will be verifying
    untrusted_jwt: String,
    // *The* way in which we expect JWTs to be issued / we will be verifying against:
    verifier: Verifier,
  ) -> ... {

    // Basic sanity checks & decoding.
    let untrusted_jwt: Jwt = ...;

    if !verifier.acceptable_alg(untrusted_jwt.alg) {
       bail;
    }
    verifier.verify(untrusted_jwt)
  }
Where `verifier` is something like `JwtRsa` or `JwtEd25519`, or `JwtHmac`. The verifier should know what few, limited algorithms to look for, and it should reject anything and everything that's not under its domain area. There's no blacklist, no guesswork. (I don't even think I'd have `acceptable_alg`; just let `verify` do that work; it has to look at that field anyways to set up, e.g., the hasher.)

I'm largely omitting¹ JWE, so perhaps there's some hidden dragon in there, or perhaps we just handle those completely separately. But for JWS, am I missing something? Unless you pass `NoneVerifier`, in which case you're explicitly opting in to alg: none and it's goriness.

Sadly, I don't think any of the top three Rust libraries do this.

¹I'm also omitting that RSA has many attached hash algorithms in JWS; one can imagine that JwtRsa might let you configure what hashers it will/will not use. As it is, some libraries take sort of this form, but split the key material off from the algorithm … letting you pass craziness like an RSA key material and HMAC-SHA256, which makes no sense. That is, what hash algorithms (if any) are possible is a function of the type of key material coming in.

¹I'm also omitting verification of the claims, which I think a library should generally handle.

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#79

Earlier quoted context omitted.

Why 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.

Speaking as a recidivist greybeard, not sure why you'd think we'd have anything to do with something as callow and unproven as Javascript.

JWT has nothing to do with javascript, other than being one of the many many languages that have JWT implementations.

Re: Auth0 JWT Auth Bypass: Case-Sensitive Blacklisting Is Harmful

#80

Earlier quoted context omitted.

Speaking as a recidivist greybeard, not sure why you'd think we'd have anything to do with something as callow and unproven as Javascript.

JWT has nothing to do with javascript, other than being one of the many many languages that have JWT implementations.

It has a huge vibe of incompetent reinwheeling that is natural to the javascript ecosystem because of the web explosion that gave us a large amount of people with no clue.
Post reply on HN