WICG / dbsc

Other
322 stars 24 forks source link

JWS algorithms are case-sensitive #41

Closed bc-pi closed 5 months ago

bc-pi commented 7 months ago

JWS algorithms are case-sensitive, per the JWS/JWA specs[1], and DBSC should consistently use the defined ones ES256 and RS256 (rather than es256 and rs256 that currently sometimes are used). Doing so would be good for lots of reasons but one is that suggesting any kind of case-insensitive treatment of alg values should be avoided due to issues like this: https://cybercx.co.nz/blog/json-web-token-validation-bypass-in-auth0-authentication-api/

[1] https://www.rfc-editor.org/rfc/rfc7515#section-4.1.1 https://www.rfc-editor.org/rfc/rfc7518.html#section-3.3 https://www.rfc-editor.org/rfc/rfc7518.html#section-3.4 https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms

kmonsen commented 7 months ago

Thank you for the comment, the reason they are lower case in the header is that parameters in structured headers can only be lower case. Happy to take input of a better way to make the headers, the main requirements are:

I could not think of a better way to do this, but if there is a better way we can adopt that.

wparad commented 7 months ago

Thank you for the comment, the reason they are lower case in the header is that parameters in structured headers can only be lower case. Happy to take input of a better way to make the headers, the main requirements are:

  • Use structured headers
  • Be able to do more than on registration in a response

I could not think of a better way to do this, but if there is a better way we can adopt that.

Can I ask for clarification on what you mean that parameters in structured headers can only be lower case? This might just be something I'm not familiar with, are you referencing RFC 8941? Because I'm looking at that right now and don't see anywhere where it says that field values must be in lowercase.

kmonsen commented 7 months ago

Yes, correct and more specifically https://www.rfc-editor.org/rfc/rfc8941.html#section-3.1.2

The headers as of right now take the algorithms as parameters and they can only be lower case. I am open to other ways of organizing the headers as long as we can meet the requirements. At the very least structured headers must be used.

wparad commented 7 months ago

Okay, well that can be fixed by specifying the algorithm as the parameter value rather than the key. Header: alg=ES256

bc-pi commented 7 months ago

Be able to do more than one registration in a response

I asked about this over here https://github.com/WICG/dbsc/issues/45#issuecomment-2048193103 too but would you be able to explain more about why more than one registration in a response needs to be supported and what it would even mean in terms of expected behavior from the browser and server?

bc-pi commented 7 months ago

Use structured headers

Lots of different ways to encode data with Structured Fields but perhaps a dictionary with an inner list value for the algorithms and string values for the other things? That might look something like this:

Sec-Session-Registration: start="/start-dbsc", refresh="/refresh-dbsc",  challenge="bwc9c3ltc7jpACC3r4", algs=("ES256" "RS256")
kmonsen commented 7 months ago

Thank you, I will look into that. Can I ask why do you want the challenge as a string instead of a byte sequence?

arnar commented 7 months ago

Because for a bytestring we have to specify how it gets decoded/encoded. Since the browser doesn't parse or manipulate it, that is unnecessary. It comes in as a string in a header, and it goes out as a string in a JWT. The most flexibility for a server is to just leave that string alone, and not require any particular encoding.

kmonsen commented 7 months ago

Actually the browser has to parse it as it is used to sign the JWT in parsed form so we do have to specify the format and if we do I think bytestring is useful.

kmonsen commented 7 months ago

Chatted offline with Arnar, we are overcomplicating it a bit for our internal prototype and will for the standards version put the string directly in the JWT as received.

bc-pi commented 7 months ago

Thanks for the update @kmonsen. And thanks @arnar for that explanation that said what I was trying to say in part of this https://github.com/WICG/dbsc/issues/45#issuecomment-2048193103 but you said it better.

kmonsen commented 7 months ago

I think you explained it well, I was lost in some of the details on how our prototype works. I'll try to update this later this week.

kmonsen commented 6 months ago

Sorry I have been away with a medical issue, but are back now.

The two proposals in this thread would not work for multiple registrations, so I have the following proposal: (RS256 ES256);path="/start1";challenge="my_challenge"

() is a list of tokens, containing one or two of RS256 ES256, other values in the list are ignored. Mandatory. "path" is a param to this list, with the value being the previous main string. Mandatory "challenge" is a param to this list, with the challenge to be used. Optional "authorization" is a param to this list, auth parameter. Optional

Other parameters are allowed, but will be ignored.

Please give feedback if you think this would not work, if I don't hear anything I will update the docs and the code later this week.

kmonsen commented 5 months ago

Updated the explainer with case sensitive algos, and it is in the latest chrome canary now.