5 ms·
> Those headers use comma both to separate challenges and to separate > parameters within a challenge, which just seems mean-spirited. Indeed. And while the r
by LukeShu 5y ago
> Those headers use comma both to separate challenges and to separate
> parameters within a challenge, which just seems mean-spirited.
Indeed. And while the resulting semantic meaning is unambiguous,
because both lists allow empty elements (well, you shouldn't emit them
but as you note, section 7 says you still need to be able to parse
them), it can be ambiguous for the parser whether an empty element
belongs to the inner list or the outer list. So you'll likely run in
to trouble if trying to use a parser-generator or generic algorithms,
even though the ambiguity is totally inconsequential.
In "Scheme1 realm=foo, , Scheme2 realm=foo", is the empty element an
empty param for the Scheme1 challenge, or an empty challenge between
the Scheme1 and Scheme2 challenges? Answer: It doesn't matter, but
good luck telling your tooling that.
> Other things about HTTP authentication that seem mean, dumb,
> annoying, or all of the above: both the RFC 2069 example response
> and the RFC 7616 SHA-512-256 example response are calculated
> incorrectly;
RFC 2069 (rev 1): Eh, the mistake is noted in the errata.
RFC 2617 (rev 2): Gets it right.
RFC 7616 (rev 3): Indeed. This has been reported as errata (way back
in 2016), but is not "verified". The report claims that the incorrect
values are obtained by naively truncating SHA-512 to 256 bits, rather
than making the other changes (using a different H⁽⁰⁾ value) for it
to be true SHA-512/256; but I haven't checked this to comment on it.
> RFC 7616's userhash field seems to require the server to do
> O(users_in_database) hashes to know what user to operate on;
I'd assume that you'd just store the H(concat(username, ":", realm))
as a column in the database, and select on that. I guess you're still
doing O(users_in_database) hashes, but you'd do a hash when you create
each user, not re-doing all of them for each request.
> RFC 7235's challenge grammar describes a token68 syntax that really
> only is used for the credentials in basic, never a challenge;
Yeah. That's weird.
> RFC 7616 drops backwards compatibility for RFC 2069 even though I
> bought a product this year that still uses RFC 2069-style
> calculations;
You don't mention that RFC 2617 set up a migration path, which RFC
7616 finally "turned off".
1997 (RFC 2069): Here's a formula.
1999 (RFC 2617): Here's a new more secure formula, servers "SHOULD"
set the "qop" parameter to opt-in to it, and clients "SHOULD" respond
in kind. But if qop is unset, then fall back to the old formula.
2015 (RFC 7616): The old formula is gone, you "MUST" set the qop
parameter to select the new formula.
That was a 16 year migration period where both were supported, during
which everyone "SHOULD" have switched to the new way.
> and it's based on old standards that followed "be conservative in
> what you do, be liberal in what you accept from others" so RFC 7230
> section 7 has separate grammars for what lists you must send and
> what lists you must accept, which further complicates parsing the
> nested lists.
You make it sound like they totally changed it; the new list syntax is
a subset of the old syntax, not something different.
Eh, there are already lots of places in the spec where it says "don't
send X... but if you receive X, you should accept+handle it anyway".
This is just one more.
- thaumasiotes 5y ago> In "Scheme1 realm=foo, , Scheme2 realm=foo", is the empty element an empty param for the Scheme1 challenge, or an empty challenge between the Scheme1 and Scheme2 challenges? Answer: It doesn't matter, but good luck telling your tooling that. If it doesn't matter, it seems like the tooling would be happy if you told it "it's an empty challenge". Or "it's an empty parameter". What's stopping you? In "1 + 2 + 3", is the parser supposed to generate (+ 1 (+ 2 3)) or (+ (+ 1 2) 3)? It doesn't matter, so you pick whichever one you want, and tell the parser to do it that way. This is a bog-standard problem to need to handle in a parser, and your tooling will definitely provide a way to handle it.
- scottlamb 5y ago> In "Scheme1 realm=foo, , Scheme2 realm=foo", is the empty element an empty param for the Scheme1 challenge, or an empty challenge between the Scheme1 and Scheme2 challenges? Answer: It doesn't matter, but good luck telling your tooling that. Yeah, I also wrote a parser generator grammar as a reference and tripped over this. I'm not real experienced with them, so it took me a bit to find the simple solution: the inner one can't consume the final comma (or the outer one won't parse due to the lack of separator, and the parser won't know to backtrack/where to), so for the inner one I just removed the portion of the rule that consumes any trailing commas. A divergence from their ABNF but oh well. > > RFC 7616's userhash field seems to require the server to do O(users_in_database) hashes to know what user to operate on; > I'd assume that you'd just store the H(concat(username, ":", realm)) as a column in the database, and select on that. I guess you're still doing O(users_in_database) hashes, but you'd do a hash when you create each user, not re-doing all of them for each request. Oh, good point. I was thinking the nonces were used in there, but they aren't. Still, it seems like such a stupid idea. The server has to maintain that extra column (per algorithm if they offer multiple), and it's just to protect the privacy of the username when the request and response are in plaintext. Who on earth thinks the username is more private than (in particular, isn't simply printed within) the actual request and response bodies? They should all be over TLS. > That was a 16 year migration period where both were supported, during which everyone "SHOULD" have switched to the new way. Right. They didn't, though. > > and it's based on old standards that followed "be conservative in what you do, be liberal in what you accept from others" so RFC 7230 section 7 has separate grammars for what lists you must send and what lists you must accept, which further complicates parsing the nested lists. > You make it sound like they totally changed it; the new list syntax is a subset of the old syntax, not something different. True, but if not for the more permissive receive format there wouldn't be the complications above.