[CDNi] Benjamin Kaduk's Discuss on draft-ietf-cdni-uri-signing-21: (with DISCUSS and COMMENT)
Benjamin Kaduk via Datatracker <noreply@ietf.org> Thu, 25 February 2021 07:17 UTC
Return-Path: <noreply@ietf.org>
X-Original-To: cdni@ietf.org
Delivered-To: cdni@ietfa.amsl.com
Received: from ietfa.amsl.com (localhost [IPv6:::1]) by ietfa.amsl.com (Postfix) with ESMTP id 1516F3A149D; Wed, 24 Feb 2021 23:17:50 -0800 (PST)
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
From: Benjamin Kaduk via Datatracker <noreply@ietf.org>
To: The IESG <iesg@ietf.org>
Cc: draft-ietf-cdni-uri-signing@ietf.org, cdni-chairs@ietf.org, cdni@ietf.org, kevin.j.ma@ericsson.com
X-Test-IDTracker: no
X-IETF-IDTracker: 7.26.0
Auto-Submitted: auto-generated
Precedence: bulk
Reply-To: Benjamin Kaduk <kaduk@mit.edu>
Message-ID: <161423747005.30483.7488522472983730896@ietfa.amsl.com>
Date: Wed, 24 Feb 2021 23:17:50 -0800
Archived-At: <https://mailarchive.ietf.org/arch/msg/cdni/yr_q2g2q8JBLF8rswhG25T_KfNI>
Subject: [CDNi] Benjamin Kaduk's Discuss on draft-ietf-cdni-uri-signing-21: (with DISCUSS and COMMENT)
X-BeenThere: cdni@ietf.org
X-Mailman-Version: 2.1.29
List-Id: "This list is to discuss issues associated with the Interconnection of Content Delivery Networks \(CDNs\)" <cdni.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/cdni>, <mailto:cdni-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/cdni/>
List-Post: <mailto:cdni@ietf.org>
List-Help: <mailto:cdni-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/cdni>, <mailto:cdni-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 25 Feb 2021 07:17:50 -0000
Benjamin Kaduk has entered the following ballot position for draft-ietf-cdni-uri-signing-21: Discuss When responding, please keep the subject line intact and reply to all email addresses included in the To and CC lines. (Feel free to cut this introductory paragraph, however.) Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html for more information about IESG DISCUSS and COMMENT positions. The document, along with other ballot positions, can be found here: https://datatracker.ietf.org/doc/draft-ietf-cdni-uri-signing/ ---------------------------------------------------------------------- DISCUSS: ---------------------------------------------------------------------- I support Éric's and Erik's and Roman's Discusses. We've had similar issues with embedding client IP addresses in security tokens all over the place, e.g., in Kerberos tickets, where it provided negligible security benefit and frequently caused (hard to diagnose!) breakage. I further note based on some of the responses so far that (as I understand it) the issues of multiple client IPs is quite realistic just for making requests to the CSP vs the uCDN, and no amount of time-locality can save us. I expect that the IESG will have some in-person discussion of this topic and what we are willing to put in an IETF-stream RFC. (My own personal opinion is that we have a fair amount of leeway to document "some people are doing this thing" accompanied by explanations of the flaws in that practice, but that we have very limited scope to recommend bad practices.) I think we should also discuss the proposed technique of redistributing shared secrets used to generate MACs for signed JWTs. I see a minimal acknowledgment that there is potential cause concern in the penultimate paragraph of the security considerations that "it is important to know the implications of a compromised shared key", but in my mind the text there does not really call out the severity of those implications. I would have expected something like "redistributing the shared key in this manner allows the dCDNs to impersonate the CSP to the uCDN and produce arbitrary signed URLs that are accepted by the uCDN as authentic". Well, what I *actually* would have expected was to just not define this mechanism at all, as it is too risky to use a group-shared symmetric key in a group where participants are at different trust levels. But perhaps the WG can produce some explanation of why this is acceptable... I also have concerns about our guidance to leave the JWT "jti" unchanged when re-signing with different contents, e.g., changing Issuer and/or Audience, etc.. We don't seem to mention one way or another whether "jti" needs to be preserved while performing Signed Token Renewal, but changing the "exp" while preserving "jti" seems like it would be problematic as well. The guidance in RFC 7519 is somewhat vague (basically, that it needs to change if it identifies a "different data object"), so we may want to consult the broader OAuth WG (not necessarily just the IANA DE) for further interpretation. I can also add based on the responses so far that the "jti" is not solely to be used to prevent replay, and so I am skeptical of reasoning based on such an argument. The combined defaults for the CDNI Metadata Interface for URI Signing seem to be an unsafe combination. Specifically, the default behavior for the "issuers" property is to allow any Issuer, and the default for the "jwt-header" property is to take the header from the JWT in band. As far as I can tell, this means that the dCDN will just blindly accept anything that is formatted as a JWT and signed by any key nown to the dCDN. The authentication and authorization properties of such behavior are so poor so as to effectively be useless, absent some level of care surrounding key management to isolate keys to given URIs. In fact, the lack of substantive discussion of key management and requirements thereof seems Discuss-worthy in its own right. We need to say something about obtaining a key along with a trust path to what it's authorized to be used for, even if the specific protocol mechanism for doing so is left out of scope. ---------------------------------------------------------------------- COMMENT: ---------------------------------------------------------------------- Balloting late in the week I have the benefit of seeing the comments of the other ADs. I've tried to suppress duplicates but no doubt have missed a few; sorry for the extra work and feel free to just reference some other discussions instead of repeating their contents. Please don't refer to the "jti" claim as a "Nonce". There is a separate registered "nonce" JWT claim that plays a different role, and mixing up the terminology is confusing, even if the JWT ID value can be used as a nonce in some circumstances (but not all). Please reference (and act on, if/as appropriate) the JWT BCP (RFC 8725). Section 1 Specifically, the CDNI Framework [RFC7336] states: The CSP may also trust the CDN operator to perform actions such as delegating traffic to additional downstream CDNs, and to enforce per-request authorization performed by the CSP using techniques such as URI Signing. In particular, the following requirement is listed in the CDNI Requirements [RFC7337]: (editorial) It reads a bit oddly to have both a "specifically" and an "in particular"; the second line might be reframed as more of an "additionally" or "also" type remark. Section 1.2 A CSP and CDN are assumed to have a trust relationship that enables the CSP to authorize access to a content item by including a set of claims in the form of a signed JWT in the URI before redirecting a UA to the CDN. [...] nit/editorial: the trust relationship is what enables the authorization of access, but using claims in a signed JWT to effectuate that is more of an implementation agreement that builds on the trust relationship than an aspect of the trust relationship itself. So this could be "enables the CSP to authorize access to a content item, which is realized in practice by including a set of claims in a signed JWT", or similar. Section 1.3 In step #3, the UA may send an HTTP request or a DNS request. Depending on whether HTTP-based or DNS-based request routing is used. [...] nit: sentence fragment. Regardless of the type of keys used, the verifying entity has to obtain the key (either the public or the symmetric key). [...] Not just obtain the key, but obtain it in a manner that allows trust to be placed in the assertions made using that key. Section 2 o URI Signing Package (URISigningPackage): The URI attribute that encapsulates all the URI Signing claims in a signed JWT encoded format. This attribute is exposed in the Signed URI as a path- style parameter or a form-style parameter. Is there a good reference for "URI attribute"? It sounds like should be a technical term but I couldn't find a clear definition. The URI Signing Package will be found by parsing any path-style parameters and form-style parameters looking for a key name matching the URI Signing Package Attribute. Both parameter styles MUST be supported to allow flexibility of operation. The first matching parameter SHOULD be taken to provide the signed JWT, though providing more than one matching key is undefined behavior. Shouldn't the metadata specify which parameter style is going to be used? (Perhaps two, rather than one, new values for cdnistt?) Section 2.1 The following claims (where the "JSON Web Token Claims" registry claim name is specified in parenthesis below) are used to enforce the distribution policies. All of the listed claims are mandatory to implement in a URI Signing implementation, but are not mandatory to use in a given signed JWT. (The "optional" and "mandatory" identifiers in square brackets refer to whether or not a given claim MUST be present in a URI Signing JWT.) The final parenthetical suggests that the previous sentence should read "not necessarily mandatory to use" (since apparently some of them *are* mandatory to use). Though I do see this was noted by Roman as well. I would be interested to hear why cdniuc is not mandatory (see below)... Note: The time on the entities that generate and verify the signed URI SHOULD be in sync. In the CDNI case, this means that CSP, uCDN, and dCDN servers need to be time-synchronized. It is RECOMMENDED to use NTP [RFC5905] for time synchronization. It's surprising that this is only a SHOULD-level requirement for time synchronization, given the scope of issues that can result if time is not synchronized. When would it be okay to ignore the SHOULD? Also, separately, I note that RFC 8915 presents Network Time Security for NTP, which might be a helpful reference (and, arguably, worth recommending in its own right). Section 2.1.x In general, my stance is that it's redundant to say that "the semantics in Section X of RFC 7519 MUST be followed", because that's inherent in the definition of the JWT claim. But you're free to write the text as you wish. Section 2.1.1 Issuer (iss) [optional] - The semantics in [RFC7519] Section 4.1.1 MUST be followed. This claim MAY be used to verify authorization of the issuer of a signed JWT and also MAY be used to confirm that the indicated key was provided by said issuer. If the CDN verifying the What is meant by "to verify authorization of the issuer of a signed JWT"? In some sense, the "iss" claim is meaningless unless the JWT signature is validated as having been generated by a trusted key associated that belongs to the "iss" identity (or the JWT was received on a trusted channel, which of course does not apply here since it's via the UA). (Also note that the JWT BCP (RFC 8725) has some things to say about when to use "iss" and how that relates to whether a given key is used in more than one context...) signed JWT does not support Issuer verification, or if the Issuer in I think this is intended to be "If an Issuer claim is present and the CDN verifying the signed JWT [...]". the signed JWT does not match the list of known acceptable Issuers, the CDN MUST reject the request. [...] I think this list also needs to include "if the Issuer claim does not match the key used to sign the JWT". Section 2.1.2 Subject (sub) [optional] - The semantics in [RFC7519] Section 4.1.2 MUST be followed. If this claim is used, it MUST be a JSON Web Encryption (JWE [RFC7516]) Object in compact serialization form, because it contains personally identifiable information. This claim While I am happy to see that the subject information is recognized as PII and required to be protected, it seems that this formulation is over-constrained. Why does the Subject specifically need to be compact-serialization-form JWE, as opposed to some other encrypted form (that cannot be correlated to other instances of the same encrypted Subject? Why does just using a signed-and-encrypted JWT for the containing JWT not suffice? contains information about the subject (for example, a user or an agent) that MAY be used to verify the signed JWT. If the received signed JWT contains a Subject claim, then any JWT subsequently generated for CDNI redirection MUST also contain a Subject claim, and the Subject value MUST be the same as in the received signed JWT. [...] Strict value equivalence seems problematic (given that we mandate compact-form JWE), since there is a key (re)distribution problem for making the information usable to any dCDN that is involved. If it's encrypted using a symmetric key, then the uCDN sharing it to the dCDN introduces the same issue as for "signed" JWTs -- the dCDN can impersonate the CSP; if it's using an asymmetric key then the set of recipients is fixed at JWE creation (by the CSP) and we either lose the ability to seamlessly add CDN tiers or have to redistribute the private key (which is against best practices), in order to meet the "byte for byte the same value" requirement. What motivates the prohibition of re-encrypting for the next level of hierarchy? Section 2.1.3 Audience (aud) [optional] - The semantics in [RFC7519] Section 4.1.3 MUST be followed. This claim is used to ensure that the CDN verifing the JWT is an intended recipient of the request. The claim should contain an identity on behalf of whom the CDN can verify the token (e.g., the CSP or any uCDN in the chain). A dCDN MAY modify the claim as long it can generate a valid signature. While RFC 7519 does say that "[t]he processing of this claim is generally application specific", the description here doesn't seem to make a whole lot of sense. It's supposed to be used by the entity receiving the JWT, which is never going to be the CSP (which generates the JWT). My intuition is that typically the CSP would issue a JWT with Audience of the uCDN (or some meta-Audience for the combination of uCDN and dCDN), and then either the uCDN would re-sign with the dCDN as the Audience or the dCDN would be configured to recognize the Audience used by the CSP as being valid for itself. Also, "the Audience used by the CSP" is perhaps ambiguous as to whether that's the one inserted by the CSP or recognized by the CSP as being itself. So maybe "recognize the Audience inserted in the JWT by the CSP"? Section 2.1.4 Expiry Time (exp) [optional] - The semantics in [RFC7519] Section 4.1.4 MUST be followed, though URI Signing implementations MUST NOT allow for any time synchronization "leeway". If the CDN Why do we have "MUST NOT allow for any [leeway]" when it's only RECOMMENDED to have synchronized time? verifying the signed JWT does not support Expiry Time verification, As above, I think this is meant to be "If the Expiry Time claim is present and the CDN verifying [...]". or if the Expiry Time in the signed JWT corresponds to a time equal to or earlier than the time of the content request, the CDN MUST reject the request. [...] Section 2.1.5 [conceptually same comments as for §2.1.4, adjusted for the "nbf" claim] Section 2.1.6 Issued At (iat) [optional] - The semantics in [RFC7519] Section 4.1.6 MUST be followed. If the received signed JWT contains an Issued At claim, then any JWT subsequently generated for CDNI redirection MUST also contain an Issued At claim, and the Issuer value MUST be updated nit: s/Issuer value/Issued At value/ Section 2.1.7 If the signed JWT contains a Nonce claim and the CDN verifying the signed JWT either does not support Nonce storage or has previously seen the Nonce used in a request for the same content, then the CDN MUST reject the request. [...] As above, this seems predicated on the "jti" claim being present in a received token. Section 2.1.9 It might be worth asking the OAuth WG if there's seen to be value in having a generic "crit" claim that protocols can require comprehension of, to hold a list of claims that are critical for that token in that protocol. If any of the listed extension claims are not understood and supported by the recipient, then the Signed JWT is invalid. [...] (editorial) In the other sections we seem to use language about "MUST reject the request" or "MUST reject the JWT" rather than just saying that the JWT "is invalid" Section 2.1.10 [same comments about encryption as for Subject] Section 2.1.11 Why is the CDNI URI Container claim optional? It seems like the URI Signing cannot be fit for purpose if the URI being signed is not contained in the token... Section 2.1.12 Can we give any guidance on what kind of values might make sense for the CDNI Expiration Time Setting field and still providing some reasonable security properties? (Conversely, what kind of values are so large so as to be nonsensical?) Section 2.1.14 The first two paragraphs seem to talk about this claim as being a direction to the client of when to send such a token along with a request, but the third paragraph seems to talk about it as being a direction to the CDN for generating new tokens as part of Signed Token Renewal. This leaves me confused about what the intended usage actually is. Section 2.1.15 The URI Container (cdniuc) claim takes one of the following forms: 'hash:' or 'regex:'. More forms may be added in the future to extend the capabilities. How will a JWT producer know whether a JWT consumer knows about any such extended functionality? Section 2.1.15.2 An example of a 'regex:' is the following: [^:]*\\://[^/]*/folder/content/quality_[^/]*/segment.{3}\\.mp4(\\?.*)? It seems a bit surprising to just do a wildcard match on scheme and assume that the path components will be meaningful for that scheme. Perhaps a variation that used branches to match only http or https schemes would be preferred? Section 3.2 this document. However, in order to also support legacy UAs that do not include any specific provisions for the handling of signed JWTs, Section 3.3 defines a mechanism using HTTP Cookies [RFC6265] that allows such UAs to support the concept of renewing signed JWTs without requiring any additional UA support. (editorial) the way this sentence is written suggests that the §3.3 cookie-based mechanism is distinct from the mechanism described here (most notably due to the use of the word "also"), but it looks like the mechanism described here also uses cookies. Are the two actually distinct? Section 3.2.1 (editorial) typically we don't use second-person language ("you") in RFC style. Section 3.3.1 In such scenarios, Signed Token Renewal of a signed JWT SHOULD be communicated via the query string instead, in a similar fashion to how regular signed JWTs (outside of Signed Token Renewal) are communicated. Note that the use of URL embedded signed JWTs SHOULD NOT be used in HTTP 2xx Successful messages, since UAs might not know how to extract the signed JWTs. I don't think I understand how (in the last sentence) a URL embedded signed JWT would be used in an HTTP 2xx response, since the response would just be normal application content and there's not a particularly well-defined place to put a URL with embedded JWT. Section 4 necessary to allow the dCDN to verify a Signed URI. Events that pertain to URI Signing (e.g., request denial or delivery after access authorization) need to be included in the logs communicated through the CDNI Logging interface. (editorial) I don't think I understand what is meant by "e.g., request denial or delivery after access authorization". I'm not even 100% sure if I'm supposed to group thing as "(request denial or delivery) (after access authorization)" or "(request denial) or (delivery after access authorization)". My initial thought was the latter, but "delivery after access authorization" really doesn't make much sense to me; my current thinking is that it's the former and that s/after access authorization/after an access authorization decision has been made/ would clarify. Section 4.4 Property: issuers Description: A list of valid Issuers against which the Issuer claim in the signed JWT may be verified. Issuers should always be tied to keys that they control. Leaving keys and issuer identities to be managed separately invites identity misbinding attacks. Property: package-attribute Description: The name to use for the URI Signing Package. (nit?) Should this be "The attribute name to use"? Property: jwt-header Description: The header part of JWT that is used for generating or verifying a signed JWT when the JWT token in the URI Signing Package does not contain a header part. (editorial) IIUC this metadata interface is for the uCDN to provide information to the dCDN that the dCDN will use for processing requests (i.e., in this case, for verifying JWTs). In that context, I don't see how it's useful to say that this is the header part of the JWT "that is used for generating", since the dCDN only needs to verify these JWTs. If the dCDN is issuing its own JWTs when acting as an uCDN in a hierarchy, it can list its own jwt-header in its own published metadata. The following is an example of a URI Signing metadata payload with explicit values: { "generic-metadata-type": "MI.UriSigning" "generic-metadata-value": { "enforce": true, "issuers": ["csp", "ucdn1", "ucdn2"], It might be more helpful to use the URI form of the Issuer names, since in this generic RFC we do not have any deployment-specific context that would allow the use of a short string issuer identifier. Section 5 URI Signing supports both HTTP-based and DNS-based request routing. JSON Web Token (JWT) [RFC7519] defines a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a signed JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted. AFAICT this is the only place in the document where we refer to a possibility of using JWE over the entire JWT (as opposed to just the Subject or IP address claim bodies). Yes, this is in some sense a generic statement about JWT and not necessarily attempting to apply to the URI Signing usage of JWT, but it still seems out of place. I would have expected that we just stick to talking about JWS (or, I suppose, that JWE was mentioned consistently throughout, but it doesn't seem to be a great fit for this application anyway). Section 5.1 2. CSP provides to the uCDN the information needed to verify signed JWTs from that CSP. For example, this information may include a key value. When would it not include a key value? 3. Using the CDNI Metadata interface, the uCDN communicates to a dCDN the information needed to verify signed JWTs from the uCDN for the given CSP. For example, this information may include the URI query string parameter name for the URI Signing Package Attribute. It would also include key material if the uCDN is re-signing, right? So either we should mention key material here or change (9) to not mention "computes". 4. When a UA requests a piece of protected content from the CSP, the CSP makes a specific authorization decision for this unique request based on its personal distribution policy. (nit) I'd suggest s/personal/local/, since the CSP is typically not a person. Section 5.2 2. CSP provides to the uCDN the information needed to verify cryptographic signatures from that CSP. For example, this information may include a key. As above, when would this not include a key value? 4. When a UA requests a piece of protected content from the CSP, the CSP makes a specific authorization decision for this unique request based on its arbitrary distribution policy. We should use a consistent term between the previous section and here (I still prefer "local" but the actual word doesn't matter very much). In general, I'd recomment harmonizing the phrasing between the two sections; there are several differences that appear when I run a diff, including "Signed URI" vs "cryptographic signature" or "signed JWTs" vs "cryptographic signatures". 12. If the verification is negative, the dCDN rejects the request and sends an error code 403 Forbidden in the HTTP response. 13. If the verification is positive, the dCDN serves the request and delivers the content. (nit) I'd suggest "verification result" both here and above. Section 6.4 is a 3DIGIT value as defined in Section 4.5. Additions to the CDNI URI Signing Verification Code namespace will conform to the "Specification Required" policy as defined in [RFC8126]. Updates to this subregistry are expected to be sparse. (nit) one might interpret "sparse" either as meaning a long time between allocations or that the numerical values assigned will not be contiguous ranges, which might be worth clarifying. (This holds for both the new registries, I think.) | 406 | RFCthis | Signed JWT verification performed and | | | | rejected because of Issued At enforcement | It's not clear to me what kind of Issued At enforcement might lead to rejection -- there is no mention of rejection made in §2.1.6, for example. Should there be a code for "only one of cdnistt and cdniets present"? Section 7 Whenever the dCDN receives a request with a given unique ID, it adds that ID to the list of 'used' IDs. In the case an illegitimate UA tries to use the same URI through a replay attack, the dCDN can deny the request based on the already- used access ID. You probably also want to mention expiring out IDs from the list of 'used' IDs when they expire, or this becomes an unbounded state-keeping requirement... Section 8 The main body text mentioned both Subject and IP address as having potential privacy concerns; why do we only mention IP address here? Section 11.2 https://www.ietf.org/about/groups/iesg/statements/normative-informative-references/ suggests that with NTP being RECOMMENDED, RFC 5905 would be classified as normative. Appendix A The "exp" times are in 2016; if regenerating the examples is automated using newer dates might be nice (but the risk of getting into an inconsistent state if redoing them by hand is too big to merit changing the dates in that case, IMO). Appendix A.3 Once the server verifies the signed JWT it will return a new signed JWT with an updated expiry time (exp) as shown below. Note the expiry time is increased by the expiration time setting (cdniets) value. This example is adding the "cdniets" value to the previous "exp" value, but the specification for this claim says that it is added to the "time at which the JWT is verified", which is unlikely to be exactly the previous "exp" value. I suggest adding a few words about this and using a different (earlier) "exp" in the re-signing example.
- [CDNi] Benjamin Kaduk's Discuss on draft-ietf-cdn… Benjamin Kaduk via Datatracker