letsencrypt / boulder

An ACME-based certificate authority, written in Go.
Mozilla Public License 2.0
5.15k stars 601 forks source link

Response to bad 'url' parameter uses incorrect error code #4729

Closed mpalmer closed 3 years ago

mpalmer commented 4 years ago

I've just noticed that sending a deliberately-mangled request that contains an incorrect url parameter in the protected header provides a very helpful error message, but not the problem type mandated by the spec:

{
  "type": "urn:ietf:params:acme:error:malformed",
  "detail": "JWS header parameter 'url' incorrect. Expected \"https://acme-staging-v02.api.letsencrypt.org/acme/revoke-cert\" got \"https://acme-staging-v02.api.letsencrypt.org/acme/revoke-cert/not-really\"",
  "status": 400
}

The Fine Spec says:

On receiving such an object in an HTTP request, the server MUST compare the "url" header parameter to the request URL. If the two do not match, then the server MUST reject the request as unauthorized.

I assume this means that the type of the error response should be urn:ietf:params:acme:error:unauthorized; whether the status should be 401 as well I'm not quite as confident about.

aarongable commented 3 years ago

There are other places in RFC8555 which much more clearly indicate that status 401 and/or urn:ietf:params:acme:error:unauthorized must be used:

Section 7.3.6:

If a server receives a POST or POST-as-GET from a deactivated account, it MUST return an error response with status code 401 (Unauthorized) and type "urn:ietf:params:acme:error:unauthorized".

Similarly, immediately adjacent to section 6.4, the return codes of other forms of invalid JWKs are also very specific:

Section 6.2:

If the client sends a JWS signed with an algorithm that the server does not support, then the server MUST return an error with status code 400 (Bad Request) and type "urn:ietf:params:acme:error:badSignatureAlgorithm".

If the server supports the signature algorithm "alg" but either does not support or chooses to reject the public key "jwk", then the server MUST return an error with status code 400 (Bad Request) and type "urn:ietf:params:acme:error:badPublicKey".

So I think it is appropriate to conclude that the RFC does not in fact require status code 401 and problem type ...:unauthorized. As such, I think it is better to prioritize uniformity with surrounding code, and stick with the "malformed" response for all violations which are caught by our JWK integrity checker.