[Forking this into two threads]

[Fork 1 of 2]

On Fri, Aug 19, 2016 at 2:30 PM, Jacob Hoffman-Andrews <j...@eff.org> wrote:

> On 08/19/2016 09:31 AM, Richard Barnes wrote:
> > Actually I thought of another reason, which is more compelling: There's
> > no specified algorithm for comparing JWKs.  Do you include, e.g., "kid"
> > or "x5t"?
> >
> > So we would need to specify a comparison algorithm.
>
> This is already a problem for each authenticated ACME POST. Right now
> the user is identified solely by their full account key, and it's up to
> the ACME server to determine how to look up a user by that key. I think
> this isn't a problem by itself. The server can do a thumbprint itself,
> preserving the option to switch hashes without breaking any clients.
>
> However, this relates to another change I've been meaning to propose:
> Identifying POSTs by account URLs instead of by key.
>

Just for clarity, I assume the proposal would be to require something like
{ "account": "accountURL" } in the JWS header instead of the "jwk" field.
Then the server would look up the appropriate JWK to verify the signature.



> This encourages servers to implement this logic:
>
>  - verify a POST using the account key from the JWS header
>  - then, look up that account key in a database of users
>
> Instead of this logic:
>
>  - look up an account's key in a database of users
>  - then, verify the POST using that account key
>
> The latter better fits the best practice of "don't process untrusted
> input until after you've verified the signature." The former is
> vulnerable if the attacker can make their own key that happens to
> coincide with another in the database.
>

However, we've already said that you can look up an account based on a
public key (#163), so if you can somehow reproduce a valid account key,
it's game over anyway.

This reminds me of the debate we had in JOSE about applying integrity
protection to parameters like "alg" and "jwk".  Yes, in general, you should
only act on verified data, but there's no point to applying integrity
protection to the inputs to the signature verification.  The only thing an
attacker can do by changing those inputs is make something fail to validate.

Given that there's no security difference between the two scenarios, I have
a pretty strong preference for identifying the key by value rather than by
the account URI.  It lets you have a clean transport layer that can do
validation before any ACME logic gets involved.

For example, if you identify keys by account URI, you need to a lookup in
the ACME DB before you can reject a bad request.  If you identify keys
directly, you can just have validation as a middleware step, which is a
natural fit for how modern web services are built.  See
https://github.com/bifurcation/rocket-skates/blob/master/lib/server/transport-server.js#L41



>
> Instead, the client can use the account URL rather than the full key to
> identify each request after registration. This requires that the server
> keep track of keys and properly validate them. It also makes lookup more
> straightforward for the server with regards to the question you raised
> about comparison of JWKs.
>
> For instance, the client could provide the account URL in the JWS "kid"
> header instead of the full key in the JWS "jwk" header.
>
> This matches nicely with your proposed use of the account URL in the
> inner key-change payload. I think providing the account URL there also
> removes the need for the oldKey field. I still strongly believe we need
> the full newKey. So we'd wind up with:
>
> account (required, string):
> The URL for account being modified.  The content of this field MUST be
> the exact string provided in the Location header field in response to
> the new-registration request that created the account.
>
> newKey (requrired, JWK):
> The JWK representation of the new key
>
_______________________________________________
Acme mailing list
Acme@ietf.org
https://www.ietf.org/mailman/listinfo/acme

Reply via email to