- From: Backman, Annabelle <richanna@amazon.com>
- Date: Mon, 17 Oct 2022 22:06:03 +0000
- To: "Dick.Hardt@gmail.com" <Dick.Hardt@gmail.com>
- CC: HTTP Working Group <ietf-http-wg@w3.org>, Tommy Pauly <tpauly@apple.com>, Mark Nottingham <mnot@mnot.net>
- Message-ID: <9A670797-BEF3-41A5-A73F-3715F1617EF0@amazon.com>
there is no guidance to an implementer when HTTP Message Signatures would be preferable to other signature mechanisms. We attempt address this in the Introduction (Section 1)<https://httpwg.org/http-extensions/draft-ietf-httpbis-message-signatures.html#name-introduction>, which describes the limitations of TLS and challenges posed by HTTP itself. using JOSE or COSE and including the @target-uri and @method values in the payload would provide the desired integrity protection This is a great solution…if the API is JOSE/COSE-based, or the developer is willing to change it. Remember SOAP? I do. One of its problems was that it required developers to shape their APIs in a certain way (i.e., as XML wrapped up in SOAP envelopes). But people tend to have Opinions about how to encode their API requests and responses – sometimes they're even backed by good, practical reasoning! – and don't respond well to someone telling them they have to rewrite their interfaces. It is possible to avoid that problem by copying signed content into a JWS (or other signed token) and adding that to the request – see the OAuth working group's DPoP draft<https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop-11> for one example of this. However this is impractical when the signed content is particularly large. Not only does it bloat the size of the request, a JWS covering a lot of content could easily exceed length limits for individual header fields imposed by HTTP server configurations. It also creates an opportunity for inconsistency: if the verifier looks at the JWS and the application looks at the message, and neither verifies that the two match…some bad guy is going to have a very good day and some good guy (or at least an OK guy?) is going to have a very bad day. Consequently, one of the authors' objectives is to provide a signature mechanism that only depends on the normatively defined aspects of HTTP messages, and does not make assumptions about things that are left to the implementer, e.g., structure and content of message bodies, non-standard header field names and values, etc. This is similar to the approach taken by OAuth 2.0, which avoids prescribing any particular format or structure of Bearer token-protected resource endpoints, other than the use of the `Authorization` header field. We see this un-opinionated approach as fundamentally necessary in order for HTTP Message Signatures to be a "general-purpose security mechanism". We can add text to this effect under Requirements (Section 1.2)<https://httpwg.org/http-extensions/draft-ietf-httpbis-message-signatures.html#name-requirements>. There are a number of common deployment models where HTTP Message Signature will not preserve @target-uri as the @target-uri is different at the application server than what the client called. One of these is where a CDN such as CloudFront serves both static and dynamic content. The CDN routes requests that match certain paths to different hosts. For example when receiving a call to https://www.example.com/api/v1/* the CDN may proxy the call to https://v1.api.example.com/* Another is where messages are routed between microservices. A message router may route calls to https://www.example.com/api/v1/people/* to http://people<http://people/> within the services network. This is addressed in Application of HTTP Message Signatures (Section 1.4)<https://httpwg.org/http-extensions/draft-ietf-httpbis-message-signatures.html#section-1.4-2.5>, and in two Security Considerations: Message Component Source and Context (Section 7.4.3)<https://httpwg.org/http-extensions/draft-ietf-httpbis-message-signatures.html#name-message-component-source-an> and Multiple Message Component Contexts (Section 7.4.4)<https://httpwg.org/http-extensions/draft-ietf-httpbis-message-signatures.html#name-multiple-message-component->. 1.4 and 7.4.3 in particular explain that the verifier may apply application-specific logic when deriving the context for a signature in order to account for transformations that are expected. 7.4.4 includes a non-normative example of how a reverse proxy such as a load balancer could add a `Forwarded` header field and its own signature to requests in order to allow a downstream verifier to verify the client's signature and verify that the transformations made to the @target-uri are acceptable. the canonicalization was non-trivial Canonicalization has been brought up before, and I confess to being very confused every time it is raised, as pretty much the only "canonicalization" in HTTP Message Signatures is the lower-casing of HTTP header field names…which I'd like to think is a relatively safe move. I've previously asked if those with this concern to share where in the spec they see the potential for canonicalization issues, but haven't gotten any responses. Is this a general concern you have that might be ameliorated by a close reading of the text, or are there specific places where you see excessive complexity or risk due to canonicalization? there were a number of non-deterministic flows The authors' believe the spec is deterministic. Have you identified ways or places where it is not? OAuth 1.0 was another example of a painful message signing standard. The initial group did not want to require HTTPS -- so they sort of reinvented it. I agree that OAuth 1.0 is a worthwhile case study – one that the authors are also familiar with. Keep in mind that unlike OAuth (1.0 or 2.0), HTTP Message Signatures is not a security protocol. Like `Digest` or `WWW-Authenticate`, it is an HTTP-level mechanism that may be used within a security protocol. I expect that much of its usage will come in the form of extensions to existing security protocols. (I intend to present a draft OAuth 2.0 extension for HTTP Message Signature-bound access tokens) We have the advantage of a decade+ of technological development since OAuth 1.0: HTTPS is much more common (verging on ubiquitous!) and there is a widely deployed API authorization protocol in the form of OAuth 2.0. For many applications this may be "good enough". However we also have more critical applications working with more sensitive data than we did in 2009, and developers of these applications are interested in going beyond the security bar presented by bearer tokens. (See: mTLS, DPoP, JWS-based client authentication in OAuth 2.0, OpenID Foundation FAPI working group adopting HTTP Message Signatures) HTTP Message Signatures can be the general purpose signing solution for those use cases that desire message-level integrity protection, and can be ignored by those who don't have that need as they already have solutions for their authorization problems. That said, crypto is still Scary and Hard. There's no way to get around that other than to have someone else do the crypto for you. To that end, I believe HTTP Message Signatures is in a better position than OAuth. As an HTTP-level mechanism, it could be naturally embedded within an HTTP library directly, or implemented as a thin wrapper/extension, keeping it further away from application code. Admittedly, "could" is doing a lot of work there. I can't point to an example of this happening yet. One thing I'd like to pursue in this regard is integration within browsers, e.g., an extension of the Fetch API to support signing of requests and verification of signatures on responses. Lastly, HTTP Message Signatures is far less prescriptive than OAuth 1.0 is regarding what must be signed. This allows it to be adopted with minimal changes to an application's API, as the application can require the components it cares about to be signed, and ignore the rest. — Annabelle Backman (she/her) richanna@amazon.com<mailto:richanna@amazon.com> On Oct 16, 2022, at 2:56 PM, Dick Hardt <dick.hardt@gmail.com<mailto:dick.hardt@gmail.com>> wrote: CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe. Hello I have feedback on the positioning of HTTP Message Signatures, and am sharing some history on message signing. FWIW I do not plan to implement or support HTTP Message Signatures (presuming I have a choice) Draft Feedback Section 1.4 "HTTP Message Signatures are designed to be a general-purpose security mechanism applicable in a wide variety of circumstances and applications. " This is a very broad statement. While true, there is no guidance to an implementer when HTTP Message Signatures would be preferable to other signature mechanisms. For example, if one only needs to sign the payload, JOSE and COSE are widely deployed and available mechanisms to ensure message integrity, and have the added benefit of supporting message secrecy. The one use case where HTTP Message Signatures are differentiated from JOSE and COSE is that HTTP headers in addition to the payload can be signed. From what I glean from the examples, the @target-uri and @method seem to be the most interesting. (please add more examples if there are others!). These message attributes are often critical to a web API, and the desire to provide integrity of these attributes is clear as there the integrity of the client's intent is preserved through intermediaries -- or so would seem. There are a number of common deployment models where HTTP Message Signature will not preserve @target-uri as the @target-uri is different at the application server than what the client called. One of these is where a CDN such as CloudFront serves both static and dynamic content. The CDN routes requests that match certain paths to different hosts. For example when receiving a call to https://www.example.com/api/v1/* the CDN may proxy the call to https://v1.api.example.com/* Another is where messages are routed between microservices. A message router may route calls to https://www.example.com/api/v1/people/* to http://people<http://people/> within the services network. In these two examples, using JOSE or COSE and including the @target-uri and @method values in the payload would provide the desired integrity protection, and optionally enable secrecy with end to end encryption. Message Signing Experience I provide the following stories as a cautionary tale on the challenges of message signing. Remember XML-DSig? I do. One of my ventures took on a consulting contract to write XML-DSig libraries for a number of popular languages. While the OSS libraries we shipped all worked -- the canonicalization was non-trivial and if I recall, there were a number of non-deterministic flows. I don't see XML-DSig used in the wild anymore besides SAML. OAuth 1.0 was another example of a painful message signing standard. The initial group did not want to require HTTPS -- so they sort of reinvented it. Despite the development of libraries to use, developers had challenges in getting it all working. I recall having code that called Twitter APIs (one of the last OAuth 1.0 holdouts) that would work intermittently depending on which one of the Twitter load balancers I hit. I led the design on what became OAuth 2.0 primarily because of the message signing concerns. The first requirement we agreed to was requiring HTTPS. My experience with XML-DSig and the messaging signing challenges of OAuth 1.0 were key inputs in the design work I did on what became JOSE. One of the first requirements was no canonicalization. Take the JSON string as is and base64url encode it. Done. /Dick
Received on Monday, 17 October 2022 22:06:19 UTC