diff --git a/bemasc-host-abnf/draft-ietf-httpbis-alias-proxy-status.html b/bemasc-host-abnf/draft-ietf-httpbis-alias-proxy-status.html index 4e3129a53..59abf0b07 100644 --- a/bemasc-host-abnf/draft-ietf-httpbis-alias-proxy-status.html +++ b/bemasc-host-abnf/draft-ietf-httpbis-alias-proxy-status.html @@ -1031,7 +1031,7 @@
The "target_host" variable is permitted to contain either a host-value
or a list of ip-addr
. The value of the "tcp_port" variable MUST match the port
rule from [RFC3986].¶
Note that IPv6 scoped addressing zone identifiers are not supported, and the colons in IPv6 addresses will normally be percent-encoded by the URI Template expansion process (see Figure 2).¶
-Note that IPv6 scoped addressing zone identifiers are not supported, and the colons in IPv6 addresses will normally be percent-encoded by the URI Template expansion process (see Figure 2).¶
+-URI template: - https://a.example/{?target_host,tcp_port} +Example URI Templates: + A: https://a.example{/target_host,tcp_port} + B: https://b.example/{?target_host*,tcp_port} -Variable assignments in RFC 6570 syntax: - target_host := ("192.0.2.1", "2001:db8::1") +Example variable assignments in RFC 6570 syntax: + 1: + target_host := "one.example" tcp_port := "443" + 2: + target_host := ("192.0.2.2", "2001:db8::2") + tcp_port := "80" -Resulting URI: -https://a.example/?target_host=192.0.2.1,2001%3Adb8%3A%3A1&tcp_port=443 + +Resulting URIs: + A + 1: + https://a.example/one.example/443 + B + 1: + https://b.example/?target_host=one.example&tcp_port=443 + A + 2: + https://a.example/192.0.2.2,2001%3Adb8%3A%3A2/80 + B + 2: + https://b.example/ + ?target_host=192.0.2.2&target_host=2001%3Adb8%3A%3A2&tcp_port=443
Internet-Draft | -DNS Aliases Proxy-Status | -January 2024 | -
Pauly | -Expires 27 July 2024 | -[Page] | -
This document defines the next-hop-aliases
HTTP Proxy-Status Parameter. This parameter carries
-the list of aliases and canonical names an intermediary received during DNS resolution as part
-of establishing a connection to the next hop.¶
This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-alias-proxy-status/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/alias-proxy-status.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-The Proxy-Status HTTP response field [PROXY-STATUS] allows intermediaries to convey -information about how they handled the request in HTTP responses sent to clients. -It defines a set of parameters that provide information, such as the name of the next -hop.¶
-[PROXY-STATUS] defines a next-hop
parameter, which can contain a hostname,
-IP address, or alias of the next hop. This parameter can contain only one such item,
-so it cannot be used to communicate a chain of aliases encountered during DNS resolution
-when connecting to the next hop.¶
Knowing the full chain of names that were used during DNS resolution via CNAME records -[DNS] is particularly useful for clients of forward proxies, in which the -client is requesting to connect to a specific target hostname using the CONNECT method -[HTTP] or UDP proxying [CONNECT-UDP]. CNAME records can be used to -"cloak" hosts that perform tracking or malicious activity behind more innocuous hostnames, -and clients such as web browsers use the chain of DNS names to influence behavior like cookie -usage policies [COOKIES] or blocking of malicious hosts.¶
-This document allows clients to receive the CNAME chain of DNS names for the next hop
-by including the list of names in a new next-hop-aliases
Proxy-Status parameter.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL -NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", -"MAY", and "OPTIONAL" in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here.¶
-The next-hop-aliases
parameter's value is a String [STRUCTURED-FIELDS] that contains
-one or more DNS names in a comma-separated list. The items in the list include all alias names and
-canonical names received in CNAME records [DNS] during the course of resolving the next hop's
-hostname using DNS, and MAY include the original requested hostname itself. The names ought to
-appear in the order in which they were received in DNS, for the sake of consistency. If there
-are multiple CNAME records in the chain, the first name in the next-hop-aliases
list would
-be the value in the CNAME record for the original hostname, and the final name in the
-next-hop-aliases
list would be the name that ultimately resolved to one or more addresses.¶
The list of DNS names in next-hop-aliases
uses a comma (",") as a separator between names.
-Note that if a comma is included in a name itself, the comma must be encoded as described in
-Section 2.1.¶
For example, consider a proxy "proxy.example.net" that receives the following records when -performing DNS resolution for the next hop "host.example.com":¶
--host.example.com. CNAME tracker.example.com. -tracker.example.com. CNAME service1.example.com. -service1.example.com. AAAA 2001:db8::1 -¶ -
The proxy could include the following proxy status in its response:¶
- -This indicates that proxy.example.net, which used the IP address "2001:db8::1" as the next hop
-for this request, encountered the names "tracker.example.com" and "service1.example.com"
-in the DNS resolution chain. Note that while this example includes both the next-hop
and
-next-hop-aliases
parameters, next-hop-aliases
can be included without including next-hop
.¶
The proxy can also include the name of the next hop as the first item in the list. This is
-particularly useful for reverse proxies when clients would not otherwise know the name of the
-next hop, and the next-hop
header is used to convey an IP address.¶
For example, consider a proxy "reverseproxy.example.net" that receives the following records -when performing DNS resolution for the next hop "host.example.com":¶
--host2.example.com. CNAME service2.example.com. -service2.example.com. AAAA 2001:db8::2 -¶ -
The proxy could include the following proxy status in its response:¶
- -The next-hop-aliases
parameter only applies when DNS was used to resolve the next hop's name, and
-does not apply in all situations. Clients can use the information in this parameter to determine
-how to use the connection established through the proxy, but need to gracefully handle situations
-in which this parameter is not present.¶
The proxy MAY send the empty string ("") as the value of next-hop-aliases
to indicate that
-no CNAME records were encountered when resolving the next hop's name.¶
DNS names commonly just contain alphanumeric characters and hyphens ("-"), although they -are allowed to contain any character ([RFC1035], Section 3.1), including a comma. To -prevent commas or other special characters in names leading to incorrect parsing, -any characters that appear in names in this list that do not belong to the set of URI -Unreserved Characters ([RFC3986], Section 2.3) MUST be percent-encoded as -defined in [RFC3986], Section 2.1.¶
-For example, consider the DNS name comma,name.example.com
. This name would be encoded
-within a next-hop-aliases
parameter as follows:¶
It is also possible for a DNS name to include a period character (".") within a label,
-instead of as a label separator. In this case, the period character MUST be first escaped
-as "\.". Since the "\" character itself will be percent-encoded, the name
-"dot\.label.example.com" would be encoded within a next-hop-aliases
parameter as follows:¶
Upon parsing this name, "dot%5C.label" MUST be treated as a single label.¶
-Similarly the "\" character in a label MUST be escaped as "\\" and then percent-encoded. -Other uses of "\" MUST NOT appear in the label after percent-decoding. For example, -if there is a DNS name "backslash\name.example.com", it would first be escaped as -"backslash\\name.example.com", and then percent-encoded as follows:¶
- -In order to include the next-hop-aliases
parameter, a proxy needs to have access to the chain
-of alias names and canonical names received in CNAME records.¶
Implementations ought to note that the full chain of names might not be available in common DNS
-resolution APIs, such as getaddrinfo
[POSIX]. getaddrinfo
does have an option for AI_CANONNAME
-(Section 6.1 of [RFC3493]), but this will only return the last name in the chain
-(the canonical name), not the alias names.¶
An implementation MAY include incomplete information in the next-hop-aliases
parameter to accommodate cases where it is unable to include the full chain, such as only including the canonical name if the implementation can only use getaddrinfo
as described above.¶
The next-hop-aliases
parameter does not include any DNSSEC information or imply that DNSSEC was used.
-The information included in the parameter can only be trusted to be valid insofar as the client
-trusts the proxy to provide accurate information. This information is intended to be used as
-a hint, and SHOULD NOT be used for making security decisions about the identity of a resource accessed
-through the proxy.¶
Inspecting CNAME chains can be used to detect cloaking of trackers or malicious hosts. However, the
-CNAME records could be omitted by a recursive or authoritative resolver that is trying to hide this form of cloaking.
-In particular, recursive or authoritative resolvers can omit these records for both clients directly performing DNS name
-resolution and proxies performing DNS name resolution on behalf of client. A malicious proxy could
-also choose to not report these CNAME chains in order to hide the cloaking. In general, clients can
-trust information included (or not included) in the next-hop-aliases
parameter to the degree
-that the proxy and any resolvers used by the proxy are trusted.¶
This document registers the "next-hop-aliases" parameter -in the "HTTP Proxy-Status Parameters" registry -<https://www.iana.org/assignments/http-proxy-status>.¶
- -Internet-Draft | -HTTP Cache Groups | -January 2024 | -
Nottingham | -Expires 27 July 2024 | -[Page] | -
This specification introduces a means of describing the relationships between stored responses in HTTP caches, "grouping" them by associating a stored response with one or more opaque strings.¶
-This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-cache-groups/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/cache-groups.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-HTTP caching [HTTP-CACHING] operates at the granularity of a single resource; the freshness of one stored response does not affect that of others. This granularity can make caching more efficient -- for example, when a page is composed of many assets that have different requirements for caching.¶
-However, there are also cases where the relationship between stored responses could be used to improve cache efficiency.¶
-For example, it's common for a set of closely-related resources to be deployed on a site, such as is the case for many JavaScript libraries and frameworks. These resources are typically deployed with long freshness lifetimes for caching. When that period passes, the cache will need to revalidate each stored response in a short period of time. Grouping these resources can be used to allow a cache to consider them all as being revalidated when any single response in the group is revalidated, removing the need to revalidate all of them individually and avoiding the associated overhead.¶
-Likewise, when some resources change, it implies that other resources may have also changed. This might be because a state-changing request has side effects on other resources, or it might be purely for administrative convenience (e.g., "invalidate this part of the site"). Grouping responses together provides a dedicated way to express these relationships, instead of relying on things like URL structure.¶
-In addition to sharing revalidation and invalidation events, the relationships indicated by grouping can also be used by caches to optimise their operation; for example, it could be used to inform the operation of cache eviction algorithms.¶
-Section 2 introduces a means of describing the relationships between a set of stored responses in HTTP caches by associating them with one or more opaque strings. It also describes how caches can use that information to apply revalidation and invalidation events to members of a group.¶
-Section 3 introduces one new source of such events: a HTTP response header that allows a state-changing response to trigger a group invalidation.¶
-These mechanisms operate within a single cache, across the stored responses associated with a single origin server. They do not address this issues of synchronising state between multiple caches (e.g., in a hierarchy or mesh), nor do they facilitate association of stored responses from disparate origins.¶
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", -"MAY", and "OPTIONAL" in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here.¶
-This specification uses the following terminology from [STRUCTURED-FIELDS]: List, String, Parameter.¶
-The Cache-Groups HTTP Response Header is a List of Strings [STRUCTURED-FIELDS]. Each member of the list is an opaque value that identifies a group that the response belongs to.¶
- -This specification defines one Parameter for Cache-Groups, "revalidate", that indicates that the resources associated with that group share revalidation; see Section 2.2.1.¶
-The ordering of members of Cache-Groups is not significant.¶
-Two responses stored in the same cache are considered to have the same group when all of the following conditions are met:¶
-They both contain a Cache-Groups response header field that contains the same String (in any position in the List), when compared character-by-character.¶
-The both share the same URI origin (per Section 4.3.1 of [HTTP]).¶
-If being considered for revalidation (Section 2.2.1), they both have the "revalidate" Parameter.¶
-A cache that successfully revalidates a stored response MAY consider any stored responses that share a group (per Section 2.1) as also being revalidated at the same time.¶
-Cache extensions can explicitly strengthen the requirement above. For example, a targeted cache control header field [TARGETED] might specify that caches processing it are required to revalidate such responses.¶
-A cache that invalidates a stored response MAY invalidate any stored responses that share groups (per Section 2.1) with that response.¶
-Cache extensions can explicitly strengthen the requirement above. For example, a targeted cache control header field [TARGETED] might specify that caches processing it are required to invalidate such responses.¶
-The Cache-Group-Invalidation response header field is a List of Strings [STRUCTURED-FIELDS]. Each member of the list is an opaque value that identifies a group that the response invalidates, per Section 2.2.2.¶
-For example, a POST request that has side effects on two cache groups could indicate that stored responses associated with either or both of those groups should be invalidated with:¶
- -The Cache-Group-Invalidation header field MUST be ignored on responses to requests that have a safe method (e.g., GET; see Section 9.2.1 of [HTTP]).¶
-A cache that receives a Cache-Group-Invalidation header field on a response to an unsafe request MAY invalidate any stored responses that share groups (per Section 2.1) with any of the listed groups.¶
-Cache extensions can explicitly strengthen the requirement above. For example, a targeted cache control header field [TARGETED] might specify that caches processing it are required to respect the Cache-Group-Invalidation signal.¶
-IANA should perform the following tasks:¶
-Enter the following into the Hypertext Transfer Protocol (HTTP) Field Name Registry:¶
- -This mechanism allows resources that share an origin to invalidate each other. Because of this, -origins that represent multiple parties (sometimes referred to as "shared hosting") might allow -one party to group its resources with those of others, or to send signals which have side effects upon them -- either invalidating stored responses or extending their lifetime.¶
-Shared hosts that wish to mitigate these risks can control access to the header fields defined in this specification.¶
-Thanks to Stephen Ludin for his review and suggestions.¶
-Internet-Draft | -Compression Dictionary Transport | -January 2024 | -
Meenan & Weiss | -Expires 27 July 2024 | -[Page] | -
This specification defines a mechanism for using designated HTTP responses -as an external dictionary for future HTTP responses for compression schemes -that support using external dictionaries (e.g., Brotli (RFC 7932) and -Zstandard (RFC 8878)).¶
-This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-compression-dictionary/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/compression-dictionary.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-This specification defines a mechanism for using designated [HTTP] responses -as an external dictionary for future HTTP responses for compression schemes -that support using external dictionaries (e.g., Brotli [RFC7932] and -Zstandard [RFC8878]).¶
-This document describes the HTTP headers used for negotiating dictionary usage -and registers media types for content encoding Brotli and Zstandard using a -negotiated dictionary.¶
-This document uses the line folding strategies described in [FOLDING].¶
-When responding to a HTTP Request, a server can advertise that the response can -be used as a dictionary for future requests for URLs that match the rules -specified in the Use-As-Dictionary response header.¶
-The Use-As-Dictionary response header is a Structured Field -[STRUCTURED-FIELDS] sf-dictionary with values for "match", "match-dest", -"ttl", "id", and "type".¶
-The "match" value of the Use-As-Dictionary header is a sf-string value -that provides the URLPattern to use for request matching -(https://urlpattern.spec.whatwg.org/).¶
-The URLPattern used for matching does not support using Regular expressions.¶
-The following algorithm will return TRUE for a valid match pattern and FALSE -for an invalid pattern that MUST NOT be used:¶
-Let MATCH be the value of "match" for the given dictionary.¶
-Let URL be the URL of the dictionary request.¶
-Let PATTERN be a URLPattern constructed by setting input=MATCH, -and baseURL=URL (https://urlpattern.spec.whatwg.org/).¶
-If PATTERN has regexp groups then return FALSE -(https://urlpattern.spec.whatwg.org/#urlpattern-has-regexp-groups).¶
-Return True.¶
-The "match" value is required and MUST be included in the -Use-As-Dictionary sf-dictionary for the dictionary to be considered valid.¶
-The "match-dest" value of the Use-As-Dictionary header is a sf-string value -that provides a request destination -(https://fetch.spec.whatwg.org/#concept-request-destination).¶
-An empty string for "match-dest" MUST match all destinations.¶
-For clients that do not support request destinations or if the value of -"match-dest" is a value that is not supported by the client then the client -MUST treat it as an empty string and match all destinations.¶
-The "match-dest" value is optional and defaults to the empty string.¶
-The "ttl" value of the Use-As-Dictionary header is a sf-integer value that -provides the time in seconds that the dictionary is valid for (time to live).¶
-The "ttl" is independent of the cache lifetime of the resource being used for -the dictionary. If the underlying resource is evicted from cache then it is -also removed but this allows for setting an explicit time to live for use as a -dictionary independent of the underlying resource in cache. Expired resources -can still be useful as dictionaries while they are in cache and can be used for -fetching updates of the expired resource. It can also be useful to artificially -limit the life of a dictionary in cases where the dictionary is updated -frequently which can help limit the number of possible incoming dictionary -variations.¶
-The "ttl" value is optional and defaults to 1209600 (14 days).¶
-The "id" value of the Use-As-Dictionary header is a sf-string value that -specifies a server identifier for the dictionary. If an "id" value is present -then it MUST be sent to the server in a "Dictionary-ID" request header when -the dictionary is advertised as being available.¶
-The server identifier MUST be treated as an opaque string by the client.¶
-The server identifier MUST NOT be relied upon by the server to guarantee the -contents of the dictionary. The dictionary hash MUST be validated before use.¶
-The "id" value string length (after any decoding) supports up to 1024 -characters.¶
-The "id" value is optional.¶
-The "type" value of the Use-As-Dictionary header is a sf-string value that -describes the file format of the supplied dictionary.¶
-"raw" is the only defined dictionary format which represents an unformatted -blob of bytes suitable for any compression scheme to use.¶
-If a client receives a dictionary with a type that it does not understand, it -MUST NOT use the dictionary.¶
-The "type" value is optional and defaults to "raw".¶
-A response that contained a response header:¶
- -Would specify matching any document request for a URL with a path prefix of -/product/ on the same [Origin] as the original request, and expiring as a -dictionary in 7 days independent of the cache lifetime of the resource.¶
-A response that contained a response header:¶
- -Would match main.js in any directory under /app/ and expiring as a dictionary -in one year.¶
-When a HTTP client makes a request for a resource for which it has an -appropriate dictionary, it can add a "Available-Dictionary" request header -to the request to indicate to the server that it has a dictionary available to -use for compression.¶
-The "Available-Dictionary" request header is a Structured Field -[STRUCTURED-FIELDS] sf-binary [SHA-256] hash of the contents of a single -available dictionary.¶
-The client MUST only send a single "Available-Dictionary" request header -with a single hash value for the best available match that it has available.¶
-For example:¶
- -To be considered as a match, the dictionary must not yet be expired as a -dictionary. When iterating through dictionaries looking for a match, the -expiration time of the dictionary is calculated by taking the last time the -dictionary was fetched and adding the "ttl" seconds from the -"Use-As-Dictionary" response. If the current time is beyond the expiration time -of the dictionary, it MUST be ignored.¶
-When a dictionary is stored as a result of a "Use-As-Dictionary" directive, it -includes "match" and "match-dest" strings that are used to match an outgoing -request from a client to the available dictionaries.¶
-Dictionaries MUST have been served from the same {Origin} as the outgoing -request to match.¶
-To see if an outbound request matches a given dictionary, the following -algorithm will return TRUE for a successful match and FALSE for no-match:¶
-If the current client supports request destinations:¶
- -Let BASEURL be the URL of the dictionary request.¶
-Let URL represent the URL of the outbound request being checked.¶
-If the {Origin} of BASEURL and the {Origin} of URL are not the same, return -FALSE.¶
-Let MATCH be the value of "match" for the given dictionary.¶
-Let PATTERN be a URLPattern constructed by setting input=MATCH, -and baseURL=BASEURL (https://urlpattern.spec.whatwg.org/).¶
-Return the result of running the "test" method of PATTERN with input=URL -(https://urlpattern.spec.whatwg.org/#ref-for-dom-urlpattern-test)¶
-When there are multiple dictionaries that match a given request URL, the client -MUST pick a single dictionary using the following rules: -1. For clients that support request destinations, a dictionary that specifies -and matches a "match-dest" takes precedence over a match that does not use a -destination. -1. Given equivalent destination precedence, the dictionary with the longest -"match" takes precedence. -1. Given equivalent destination and match length precedence, the most recently -fetched dictionary takes precedence.¶
-When a HTTP client makes a request for a resource for which it has an -appropriate dictionary and the dictionary was stored with a server-provided -"id" in the Use-As-Dictionary response then the client MUST echo the stored -"id" in a "Dictionary-ID" request header.¶
-The "Dictionary-ID" request header is a Structured Field [STRUCTURED-FIELDS] -sf-string of up to 1024 characters (after any decoding) and MUST be identical -to the server-provided "id".¶
-For example:¶
- -When a HTTP server responds with a resource that is encoded with a dictionary -the server MUST send the hash of the dictionary that was used in the -"Content-Dictionary" response header.¶
-The "Content-Dictionary" response header is a Structured Field -[STRUCTURED-FIELDS] sf-dictionary [SHA-256] hash of the contents of the -dictionary that was used to encode the response.¶
-If the HTTP response contains a "Content-Dictionary" response header with the -hash of a dictionary that the client does not have available then the client -cannot decode or use the HTTP response.¶
-For example:¶
- -When a compression dictionary is available for use for a given request, the -algorithm to be used is negotiated through the regular mechanism for -negotiating content encoding in HTTP.¶
-This document introduces two new content encoding algorithms:¶
-Content-Encoding | -Description | -
---|---|
br-d | -Brotli using an external compression dictionary | -
zstd-d | -Zstandard using an external compression dictionary | -
The dictionary to use is negotiated separately and advertised in the -"Available-Dictionary" request header.¶
-The client adds the algorithms that it supports to the "Accept-Encoding" -request header. e.g.:¶
- -If a server supports one of the dictionary algorithms advertised by the client -and chooses to compress the content of the response using the dictionary that -the client has advertised then it sets the "Content-Encoding" response header -to the appropriate value for the algorithm selected. e.g.:¶
- -If the response is cacheable, it MUST include a "Vary" header to prevent caches -serving dictionary-compressed resources to clients that don't support them or -serving the response compressed with the wrong dictionary:¶
- -IANA is asked to update the "HTTP Content Coding Registry" registry -([HTTP]) according to the table below:¶
-Name | -Description | -Reference | -
---|---|---|
br-d | -A stream of bytes compressed using the Brotli protocol with an external dictionary | -- [RFC7932] - | -
zstd-d | -A stream of bytes compressed using the Zstandard protocol with an external dictionary | -- [RFC8878] - | -
IANA is asked to update the -"Hypertext Transfer Protocol (HTTP) Field Name Registry" registry -([HTTP]) according to the table below:¶
-Field Name | -Status | -Reference | -
---|---|---|
Use-As-Dictionary | -permanent | -- Section 2.1 of this document | -
Available-Dictionary | -permanent | -- Section 2.2 of this document | -
Dictionary-ID | -permanent | -- Section 2.3 of this document | -
Content-Dictionary | -permanent | -- Section 2.4 of this document | -
To minimize the risk of middle-boxes incorrectly processing -dictionary-compressed responses, compression dictionary transport MUST only -be used in secure contexts (HTTPS).¶
-The security considerations for Brotli [RFC7932] and Zstandard -[RFC8878] apply to the dictionary-based versions of the respective -algorithms.¶
-The dictionary must be treated with the same security precautions as -the content, because a change to the dictionary can result in a -change to the decompressed content.¶
-The dictionary is validated using a SHA-256 hash of the content to make sure -that the client and server are both using the same dictionary. The strength -of the SHA-256 hash algorithm isn't explicitly needed to counter attacks -since the dictionary is being served from the same origin as the content. That -said, if a weakness is discovered in SHA-256 and it is determined that the -dictionary negotiation should use a different hash algorithm, the -"Use-As-Dictionary" response header can be extended to specify a different -algorithm and the server would just ignore any "Available-Dictionary" requests -that do not use the updated hash.¶
-The CRIME attack shows that it's a bad idea to compress data from -mixed (e.g. public and private) sources -- the data sources include -not only the compressed data but also the dictionaries. For example, -if you compress secret cookies using a public-data-only dictionary, -you still leak information about the cookies.¶
-Not only can the dictionary reveal information about the compressed -data, but vice versa, data compressed with the dictionary can reveal -the contents of the dictionary when an adversary can control parts of -data to compress and see the compressed size. On the other hand, if -the adversary can control the dictionary, the adversary can learn -information about the compressed data.¶
-If any of the mitigations do not pass, the client MUST drop the response and -return an error.¶
-To make sure that a dictionary can only impact content from the same origin -where the dictionary was served, the URLPattern used for matching a -dictionary to requests is guaranteed to be for the same origin that the -dictionary is served from.¶
-For clients, like web browsers, that provide additional protection against the -readability of the payload of a response and against user tracking, additional -protections MUST be taken to make sure that the use of dictionary-based -compression does not reveal information that would not otherwise be available.¶
-In these cases, dictionary compression MUST only be used when both the -dictionary and the compressed response are fully readable by the client.¶
-In browser terms, that means that both are either same-origin to the context -they are being fetched from or that the response is cross-origin and passes -the CORS check (https://fetch.spec.whatwg.org/#cors-check).¶
-On the client-side, same-origin determination is defined in the fetch spec (https://html.spec.whatwg.org/multipage/browsers.html#origin).¶
-On the server-side, a request with a "Sec-Fetch-Site:" request header with a value of "same-origin" is to be considered a same-origin request.¶
- -For requests that are not same-origin (Section 6.3.2.1), the "mode" of the request can be used to determine the readability of the response.¶
-For clients that conform to the fetch spec, the mode of the request is stored in the RequestMode attribute of the request (https://fetch.spec.whatwg.org/#requestmode).¶
-For servers responding to clients that expose the request mode information, the value of the mode is sent in the "Sec-Fetch-Mode" request header.¶
-If a "Sec-Fetch-Mode" request header is not present, the server SHOULD allow for the dictionary compression to be used.¶
-If the mode is "navigate" or "same-origin":¶
- -If the mode is "cors":¶
-For clients, apply the CORS check from the fetch spec (https://fetch.spec.whatwg.org/#cors-check) which includes credentials checking restrictions that may not be possible to check on the server.¶
- -For servers:¶
-If the response does not include an "Access-Control-Allow-Origin" response header:¶
- -If the request does not include an "Origin" request header:¶
- -If the value of the "Access-Control-Allow-Origin" response header is "*":¶
- -If the value of the "Access-Control-Allow-Origin" response header matches the value of the "Origin" request header:¶
- -If the mode is any other value (including "no-cors"):¶
- -Since dictionaries are advertised in future requests using the hash of the -content of the dictionary, it is possible to abuse the dictionary to turn it -into a tracking cookie.¶
-To mitigate any additional tracking concerns, clients MUST treat dictionaries -in the same way that they treat cookies. This includes partitioning the storage -as cookies are partitioned as well as clearing the dictionaries whenever -cookies are cleared.¶
-Internet-Draft | -Templated CONNECT-TCP | -January 2024 | -
Schwartz | -Expires 27 July 2024 | -[Page] | -
TCP proxying using HTTP CONNECT has long been part of the core HTTP specification. However, this proxying functionality has several important deficiencies in modern HTTP environments. This specification defines an alternative HTTP proxy service configuration for TCP connections. This configuration is described by a URI Template, similar to the CONNECT-UDP and CONNECT-IP protocols.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-HTTP has used the CONNECT method for proxying TCP connections since HTTP/1.1. When using CONNECT, the request target specifies a host and port number, and the proxy forwards TCP payloads between the client and this destination ([RFC9110], Section 9.3.6). To date, this is the only mechanism defined for proxying TCP over HTTP. In this specification, this is referred to as a "classic HTTP CONNECT proxy".¶
-HTTP/3 uses a UDP transport, so it cannot be forwarded using the pre-existing CONNECT mechanism. To enable forward proxying of HTTP/3, the MASQUE effort has defined proxy mechanisms that are capable of proxying UDP datagrams [CONNECT-UDP], and more generally IP datagrams [CONNECT-IP]. The destination host and port number (if applicable) are encoded into the HTTP resource path, and end-to-end datagrams are wrapped into HTTP Datagrams [RFC9297] on the client-proxy path.¶
-HTTP clients can be configured to use proxies by selecting a proxy hostname, a port, and whether to use a security protocol. However, CONNECT requests using the proxy do not carry this configuration information. Instead, they only indicate the hostname and port of the target. This prevents any HTTP server from hosting multiple distinct proxy services, as the server cannot distinguish them by path (as with distinct resources) or by origin (as in "virtual hosting").¶
-The absence of an explicit origin for the proxy also rules out the usual defenses against server port misdirection attacks (see Section 7.4 of [RFC9110]) and creates ambiguity about the use of origin-scoped response header fields (e.g., "Alt-Svc" [RFC7838], "Strict-Transport-Security" [RFC6797]).¶
-Classic HTTP CONNECT proxies can be used to reach a target host that is specified as a domain name or an IP address. However, because only a single target host can be specified, proxy-driven Happy Eyeballs and cross-IP fallback can only be used when the host is a domain name. For IP-targeted requests to succeed, the client must know which address families are supported by the proxy via some out-of-band mechanism, or open multiple independent CONNECT requests and abandon any that prove unnecessary.¶
-This specification describes an alternative mechanism for proxying TCP in HTTP. Like [CONNECT-UDP] and [CONNECT-IP], the proxy service is identified by a URI Template. Proxy interactions reuse standard HTTP components and semantics, avoiding changes to the core HTTP protocol.¶
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", -"MAY", and "OPTIONAL" in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here.¶
-A template-driven TCP transport proxy for HTTP is identified by a URI Template [RFC6570] containing variables named "target_host" and "tcp_port". The client substitutes the destination host and port number into these variables to produce the request URI.¶
-The "target_host" variable MUST be a domain name, an IP address literal, or a list of IP addresses. The "tcp_port" variable MUST be a single integer. If "target_host" is a list (as in Section 2.4.2 of [RFC6570]), the server SHOULD perform the same connection procedure as if these addresses had been returned in response to A and AAAA queries for a domain name.¶
-In HTTP/1.1, the client uses the proxy by issuing a request as follows:¶
-The method SHALL be "GET".¶
-The request SHALL include a single "Host" header field containing the origin of the proxy.¶
-The request SHALL include a "Connection" header field with the value "Upgrade". (Note that this requirement is case-insensitive as per Section 7.6.1 of [RFC9110].)¶
-The request SHALL include an "Upgrade" header field with the value "connect-tcp".¶
-The request's target SHALL correspond to the URI derived from expansion of the proxy's URI Template.¶
-If the request is well-formed and permissible, the proxy MUST attempt the TCP connection before returning its response header. If the TCP connection is successful, the response SHALL be as follows:¶
-The HTTP status code SHALL be "101 (Switching Protocols)".¶
-The response SHALL include a "Connection" header field with the value "Upgrade".¶
-The response SHALL include a single "Upgrade" header field with the value "connect-tcp".¶
-If the request is malformed or impermissible, the proxy MUST return a 4XX error code. If a TCP connection was not established, the proxy MUST NOT switch protocols to "connect-tcp", and the client MAY reuse this connection for additional HTTP requests.¶
-After a success response is returned, the connection SHALL conform to all the usual requirements for classic CONNECT proxies in HTTP/1.1 ([RFC9110], Section 9.3.6). Additionally, if the proxy observes a connection error from the client (e.g., a TCP RST, TCP timeout, or TLS error), it SHOULD send a TCP RST to the target. If the proxy observes a connection error from the target, it SHOULD send a TLS "internal_error" alert to the client, or set the TCP RST bit if TLS is not in use.¶
--Client Proxy - -GET /proxy?target_host=192.0.2.1&tcp_port=443 HTTP/1.1 -Host: example.com -Connection: Upgrade -Upgrade: connect-tcp - -** Proxy establishes a TCP connection to 192.0.2.1:443 ** - - HTTP/1.1 101 Switching Protocols - Connection: Upgrade - Upgrade: connect-tcp --
In HTTP/2 and HTTP/3, the client uses the proxy by issuing an "extended CONNECT" request as follows:¶
-The :method pseudo-header field SHALL be "CONNECT".¶
-The :protocol pseudo-header field SHALL be "connect-tcp".¶
-The :authority pseudo-header field SHALL contain the authority of the proxy.¶
-The :path and :scheme pseudo-header fields SHALL contain the path and scheme of the request URI derived from the proxy's URI Template.¶
-From this point on, the request and response SHALL conform to all the usual requirements for classic CONNECT proxies in this HTTP version (see Section 8.5 of [RFC9113] and Section 4.4 of [RFC9114]).¶
--HEADERS -:method = CONNECT -:scheme = https -:authority = request-proxy.example -:path = /proxy?target_host=192.0.2.1,2001:db8::1&tcp_port=443 -:protocol = connect-tcp -... --
Ordinary HTTP headers apply only to the single resource identified in the request or response. An origin-scoped HTTP header is a special response header that is intended to change the client's behavior for subsequent requests to any resource on this origin.¶
-Unlike classic HTTP CONNECT proxies, a templated TCP proxy has an unambiguous origin of its own. Origin-scoped headers apply to this origin when they are associated with a templated TCP proxy response. Here are some origin-scoped headers that could potentially be sent by a templated TCP proxy:¶
- -Authentication to a templated TCP proxy normally uses ordinary HTTP authentication via the "401 (Unauthorized)" response code, the "WWW-Authenticate" response header field, and the "Authorization" request header field ([RFC9110], Section 11.6). A templated TCP proxy does not use the "407 (Proxy Authentication Required)" response code and related header fields ([RFC9110], Section 11.7) because they do not traverse HTTP gateways (see Section 7).¶
-Clients SHOULD assume that all proxy resources generated by a single template share a protection space (i.e., a realm) ([RFC9110], Section 11.5). For many authentication schemes, this will allow the client to avoid waiting for a "401 (Unauthorized)" response before each new connection through the proxy.¶
-This section discusses some behaviors that are permitted or recommended in order to enhance the performance or functionality of connection setup.¶
-When using this specification in HTTP/2 or HTTP/3, clients MAY start sending TCP stream content optimistically, subject to flow control limits (Section 5.2 of [RFC9113] or Section 4.1 of [RFC9000]). Proxies MUST buffer this "optimistic" content until the TCP stream becomes writable, and discard it if the TCP connection fails. (This "optimistic" behavior is not permitted in HTTP/1.1 because it would interfere with reuse of the connection after an error response such as "401 (Unauthorized)".)¶
-Servers that host a proxy under this specification MAY offer support for TLS early data in accordance with [RFC8470]. Clients MAY send "connect-tcp" requests in early data, and MAY include "optimistic" TCP content in early data (in HTTP/2 and HTTP/3). At the TLS layer, proxies MAY ignore, reject, or accept the early_data
extension ([RFC8446], Section 4.2.10). At the HTTP layer, proxies MAY process the request immediately, return a "425 (Too Early)" response ([RFC8470], Section 5.2), or delay some or all processing of the request until the handshake completes. For example, a proxy with limited anti-replay defenses might choose to perform DNS resolution of the target_host
when a request arrives in early data, but delay the TCP connection until the TLS handshake completes.¶
This specification supports the "Expect: 100-continue" request header ([RFC9110], Section 10.1.1) in any HTTP version. The "100 (Continue)" status code confirms receipt of a request at the proxy without waiting for the proxy-destination TCP handshake to succeed or fail. This might be particularly helpful when the destination host is not responding, as TCP handshakes can hang for several minutes before failing. Implementation of "100 (Continue)" support is OPTIONAL for clients and REQUIRED for proxies.¶
-Proxies implementing this specification SHOULD include a "Proxy-Status" response header [RFC9209] in any success or failure response (i.e., status codes 101, 2XX, 4XX, or 5XX) to support advanced client behaviors and diagnostics. In HTTP/2 or HTTP/3, proxies MAY additionally send a "Proxy-Status" trailer in the event of an unclean shutdown.¶
-For server operators, template-driven TCP proxies are particularly valuable in situations where virtual-hosting is needed, or where multiple proxies must share an origin. For example, the proxy might benefit from sharing an HTTP gateway that provides DDoS defense, performs request sanitization, or enforces user authorization.¶
-The URI template can also be structured to generate high-entropy Capability URLs [CAPABILITY], so that only authorized users can discover the proxy service.¶
-Clients that support both classic HTTP CONNECT proxies and template-driven TCP proxies MAY accept both types via a single configuration string. If the configuration string can be parsed as a URI Template containing the required variables, it is a template-driven TCP proxy. Otherwise, it is presumed to represent a classic HTTP CONNECT proxy.¶
-In some cases, it is valuable to allow "connect-tcp" clients to reach "connect-tcp"-only proxies when using a legacy configuration method that cannot convey a URI template. To support this arrangement, clients SHOULD treat certain errors during classic HTTP CONNECT as indications that the proxy might only support "connect-tcp":¶
-In HTTP/1.1: the response status code is "426 (Upgrade Required)", with an "Upgrade: connect-tcp" response header.¶
-In any HTTP version: the response status code is "501 (Not Implemented)".¶
-Requires SETTINGS_ENABLE_CONNECT_PROTOCOL to have been negotiated in HTTP/2 or HTTP/3.¶
-If the client infers that classic HTTP CONNECT is not supported, it SHOULD retry the request using the registered default template for "connect-tcp":¶
--https://$PROXY_HOST:$PROXY_PORT/.well-known/masque - /tcp/{target_host}/{tcp_port}/ --
If this request succeeds, the client SHOULD record a preference for "connect-tcp" to avoid further retry delays.¶
-The names of the variables in the URI Template uniquely identify the capabilities of the proxy. Undefined variables are permitted in URI Templates, so a single template can be used for multiple purposes.¶
-Multipurpose templates can be useful when a single client may benefit from access to multiple complementary services (e.g., TCP and UDP), or when the proxy is used by a variety of clients with different needs.¶
--https://proxy.example/{?target_host,tcp_port,target_port, - target,ipproto,dns} --
Template-driven TCP proxying is largely subject to the same security risks as classic HTTP CONNECT. For example, any restrictions on authorized use of the proxy (see [RFC9110], Section 9.3.6) apply equally to both.¶
-A small additional risk is posed by the use of a URI Template parser on the client side. The template input string could be crafted to exploit any vulnerabilities in the parser implementation. Client implementers should apply their usual precautions for code that processes untrusted inputs.¶
-Templated TCP proxies can make use of standard HTTP gateways and path-routing to ease implementation and allow use of shared infrastructure. However, current gateways might need modifications to support TCP proxy services. To be compatible, a gateway must:¶
-support Extended CONNECT (if acting as an HTTP/2 or HTTP/3 server).¶
-support HTTP/1.1 Upgrade to "connect-tcp" (if acting as an HTTP/1.1 server)¶
-only after forwarding the upgrade request to the origin and observing a success response.¶
-forward the "connect-tcp" protocol to the origin.¶
-convert "connect-tcp" requests between all supported HTTP server and client versions.¶
-allow any "Proxy-Status" headers to traverse the gateway.¶
-IF APPROVED, IANA is requested to add the following entry to the HTTP Upgrade Token Registry:¶
- -IF APPROVED, IANA is requested to add the following entry to the "MASQUE URI Suffixes" registry:¶
-Path Segment | -Description | -Reference | -
---|---|---|
tcp | -TCP Proxying | -(This document) | -
Thanks to Amos Jeffries, Tommy Pauly, Kyle Nekritz, David Schinazi, and Kazuho Oku for close review and suggested changes.¶
-Internet-Draft | -Digest Fields | -January 2024 | -
Polli & Pardue | -Expires 27 July 2024 | -[Page] | -
This document defines HTTP fields that support integrity digests. The -Content-Digest field can be used for the integrity of HTTP message content. The -Repr-Digest field can be used for the integrity of HTTP representations. -Want-Content-Digest and Want-Repr-Digest can be used to indicate a sender's -interest and preferences for receiving the respective Integrity fields.¶
-This document obsoletes RFC 3230 and the Digest and Want-Digest HTTP -fields.¶
-This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-digest-headers/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/digest-headers.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-HTTP does not define the means to protect the data integrity of content or -representations. When HTTP messages are transferred between endpoints, lower layer -features or properties such as TCP checksums or TLS records [TLS] can provide -some integrity protection. However, transport-oriented integrity provides a -limited utility because it is opaque to the application layer and only covers -the extent of a single connection. HTTP messages often travel over a chain of -separate connections. In between connections there is a possibility for -data corruption. An HTTP integrity mechanism can provide -the means for endpoints, or applications using HTTP, to detect data corruption -and make a choice about how to act on it. An example use case is to aid -fault detection and diagnosis across system boundaries.¶
-This document defines two digest integrity mechanisms for HTTP. -First, content integrity, which acts on conveyed content (Section 6.4 of [HTTP]). -Second, representation data integrity, which acts on representation data (Section 8.1 of [HTTP]). This supports advanced use cases such as validating the -integrity of a resource that was reconstructed from parts retrieved using -multiple requests or connections.¶
-This document obsoletes RFC 3230 and therefore the Digest and Want-Digest HTTP -fields; see Section 1.3.¶
-This document is structured as follows:¶
-New request and response header and trailer field definitions.¶
- -Considerations specific to representation data integrity.¶
-Section 3.1 (State-changing requests),¶
-Section 3.2 (Content-Location),¶
-Appendix A contains worked examples of Representation data -in message exchanges, and¶
-Appendix B and Appendix C contain worked examples -of Repr-Digest and Want-Repr-Digest fields in message exchanges.¶
-Section 5 presents hash algorithm considerations and defines -registration procedures for future entries.¶
-The HTTP fields defined in this document can be used for HTTP integrity. Senders -choose a hashing algorithm and calculate a digest from an input related to the -HTTP message. The algorithm identifier and digest are transmitted in an HTTP -field. Receivers can validate the digest for integrity purposes. Hashing -algorithms are registered in the "Hash Algorithms for HTTP Digest Fields" registry (see -Section 7.2).¶
-Selecting the data on which digests are calculated depends on the use case of the -HTTP messages. This document provides different fields for HTTP representation -data and HTTP content.¶
-There are use cases where a simple digest of the HTTP content bytes is
-required. The Content-Digest
request and response header and trailer field is
-defined to support digests of content (Section 6.4 of [HTTP]); see
-Section 2.¶
For more advanced use cases, the Repr-Digest
request and response header
-and trailer field (Section 3) is defined. It contains a digest value
-computed by applying a hashing algorithm to selected representation data
-(Section 8.1 of [HTTP]). Basing Repr-Digest
on the selected
-representation makes it straightforward to apply it to use cases where the
-message content requires some sort of manipulation to be considered as
-representation of the resource or content conveys a partial representation of a resource,
-such as Range Requests (see Section 14 of [HTTP]).¶
Content-Digest
and Repr-Digest
support hashing algorithm agility.
-The Want-Content-Digest
and Want-Repr-Digest
fields allow
-endpoints to express interest in Content-Digest
and Repr-Digest
-respectively, and to express algorithm preferences in either.¶
Content-Digest
and Repr-Digest
are collectively termed
-Integrity fields.
-Want-Content-Digest
and Want-Repr-Digest
are
-collectively termed Integrity preference fields.¶
Integrity fields are tied to the Content-Encoding
-and Content-Type
header fields. Therefore, a given resource may have multiple
-different digest values when transferred with HTTP.¶
Integrity fields apply to HTTP message content or HTTP representations. They do -not apply to HTTP messages or fields. However, they can be combined with other -mechanisms that protect metadata, such as digital signatures, in order to -protect the phases of an HTTP exchange in whole or in part. For example, HTTP -Message Signatures [SIGNATURES] could be used to sign Integrity fields, thus -providing coverage for HTTP content or representation data.¶
-This specification does not define means for authentication, authorization, or privacy.¶
-[RFC3230] defined the Digest
and Want-Digest
HTTP fields for HTTP integrity.
-It also coined the term "instance" and "instance manipulation" in order to
-explain concepts that are now more universally defined, and implemented, as HTTP
-semantics such as selected representation data (Section 8.1 of [HTTP]).¶
Experience has shown that implementations of [RFC3230] have interpreted the -meaning of "instance" inconsistently, leading to interoperability issues. The -most common issue relates to the mistake of calculating the digest using (what -we now call) message content, rather than using (what we now call) -representation data as was originally intended. Interestingly, time has also -shown that a digest of message content can be beneficial for some use cases. So -it is difficult to detect if non-conformance to [RFC3230] is intentional or -unintentional.¶
-In order to address potential inconsistencies and ambiguity across
-implementations of Digest
and Want-Digest
, this document obsoletes
-[RFC3230]. The Integrity fields (Sections 2 and
-3) and Integrity preference fields (Section 4)
-defined in this document are better aligned with current HTTP semantics and
-have names that more clearly articulate the intended usages.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", -"MAY", and "OPTIONAL" in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here.¶
-This document uses the Augmented BNF defined in [RFC5234] and updated by -[RFC7405]. This includes the rules: CR (carriage -return), LF (line feed), and CRLF (CR LF).¶
-This document uses the following terminology from Section 3 of [STRUCTURED-FIELDS] to specify syntax and parsing: -Boolean, Byte Sequence, Dictionary, Integer, and List.¶
-The definitions "representation", "selected representation", "representation -data", "representation metadata", "user agent", and "content" in this document are to be -interpreted as described in [HTTP].¶
-This document uses the line folding strategies -described in [FOLDING].¶
-Hashing algorithm names respect the casing used in their definition document (e.g., SHA-1, CRC32c).¶
-HTTP messages indicate hashing algorithms using an Algorithm Key (algorithms). -Where the document refers to an Algorithm Key in prose, it is quoted (e.g., "sha", "crc32c").¶
-The term "checksum" describes the output of the application of an algorithm -to a sequence of bytes, -whereas "digest" is only used in relation to the value contained in the fields.¶
-Integrity fields: collective term for Content-Digest
and Repr-Digest
¶
Integrity preference fields: collective term for Want-Repr-Digest
and Want-Content-Digest
¶
The Content-Digest
HTTP field can be used in requests and responses to
-communicate digests that are calculated using a hashing algorithm applied to
-the actual message content (see Section 6.4 of [HTTP]). It is a
-Dictionary
(see Section 3.2 of [STRUCTURED-FIELDS])
-where each:¶
key conveys the hashing algorithm (see Section 5) -used to compute the digest;¶
-value is a Byte Sequence
(Section 3.3.5 of [STRUCTURED-FIELDS]), that
-conveys an encoded version of the byte output produced by the digest
-calculation.¶
For example:¶
- -The Dictionary
type can be used, for example, to attach multiple digests
-calculated using different hashing algorithms in order to support a population
-of endpoints with different or evolving capabilities. Such an approach could
-support transitions away from weaker algorithms (see Section 6.6).¶
A recipient MAY ignore any or all digests. Application-specific behavior or -local policy MAY set additional constraints on the processing and validation -practices of the conveyed digests. -The security considerations covers some of the issues related to -ignoring digests (see Section 6.6) -and validating multiple digests (see Section 6.7).¶
-A sender MAY send a digest without -knowing whether the recipient supports a given hashing algorithm, or even knowing -that the recipient will ignore it.¶
-Content-Digest
can be sent in a trailer section.
-In this case,
-Content-Digest
MAY be merged into the header section; see Section 6.5.1 of [HTTP].¶
The Repr-Digest
HTTP field can be used in requests and responses to
-communicate digests that are calculated using a hashing algorithm applied to
-the entire selected representation data (see Section 8.1 of [HTTP]).¶
Representations take into account the effect of the HTTP semantics on -messages. For example, the content can be affected by Range Requests or methods -such as HEAD, while the way the content is transferred "on the wire" is -dependent on other transformations (e.g., transfer codings for HTTP/1.1 - see -Section 6.1 of [HTTP/1.1]). To help illustrate HTTP representation concepts, -several examples are provided in Appendix A.¶
-When a message has no representation data it is still possible to assert that no -representation data was sent by computing the digest on an empty -string (see Section 6.3).¶
-Repr-Digest
is a Dictionary
(see Section 3.2 of [STRUCTURED-FIELDS]) where each:¶
key conveys the hashing algorithm (see Section 5) -used to compute the digest;¶
-value is a Byte Sequence
, that conveys an encoded version of the byte
-output produced by the digest calculation.¶
For example:¶
- -The Dictionary
type can be used, for example, to attach multiple digests
-calculated using different hashing algorithms in order to support a population
-of endpoints with different or evolving capabilities. Such an approach could
-support transitions away from weaker algorithms (see Section 6.6).¶
A recipient MAY ignore any or all digests. Application-specific behavior or -local policy MAY set additional constraints on the processing and validation -practices of the conveyed digests. -The security considerations covers some of the issues related to -ignoring digests (see Section 6.6) -and validating multiple digests (see Section 6.7).¶
-A sender MAY send a digest without knowing whether the -recipient supports a given hashing algorithm, or even knowing that the recipient -will ignore it.¶
-Repr-Digest
can be sent in a trailer section.
-In this case,
-Repr-Digest
MAY be merged into the header section; see Section 6.5.1 of [HTTP].¶
When the representation enclosed in a state-changing request -does not describe the target resource, -the representation digest MUST be computed on the -representation data. -This is the only possible choice because representation digest requires complete -representation metadata (see Section 3).¶
-In responses,¶
-if the representation describes the status of the request,
-Repr-Digest
MUST be computed on the enclosed representation
- (see Appendix B.8);¶
if there is a referenced resource
-Repr-Digest
MUST be computed on the selected representation of the referenced resource
- even if that is different from the target resource.
- That might or might not result in computing Repr-Digest
on the enclosed representation.¶
The latter case is done according to the HTTP semantics of the given
-method, for example using the Content-Location
header field (see Section 8.7 of [HTTP]).
-In contrast, the Location
header field does not affect Repr-Digest
because
-it is not representation metadata.¶
For example, in PATCH
requests, the representation digest
-will be computed on the patch document
-because the representation metadata refers to the patch document and not
-to the target resource (see Section 2 of [PATCH]).
-In responses, instead, the representation digest will be computed on the selected
-representation of the patched resource.¶
When a state-changing method returns the Content-Location
header field, the
-enclosed representation refers to the resource identified by its value and
-Repr-Digest
is computed accordingly.
-An example is given in Appendix B.7.¶
Senders can indicate their interest in Integrity fields and hashing algorithm
-preferences using the
-Want-Content-Digest
or Want-Repr-Digest
fields. These can be used in both
-requests and responses.¶
Want-Content-Digest
indicates that the sender would like to receive a content digest
-on messages associated with the request URI and representation metadata, using
-the Content-Digest
field.¶
Want-Repr-Digest
indicates that the sender would like to receive a representation digest
-on messages associated with the request URI and representation metadata, using
-the Repr-Digest
field.¶
If Want-Content-Digest
or Want-Repr-Digest
are used in a response, it
-indicates that the server would like the client to provide the respective
-Integrity field on future requests.¶
Integrity preference fields are only a hint. The receiver of the field can -ignore it and send an Integrity field using any algorithm or omit the field -entirely, for example see Appendix C.2. It is not -a protocol error if preferences are ignored. Applications that use Integrity -fields and Integrity preferences can define expectations or constraints that -operate in addition to this specification. Ignored preferences are an -application-specific concern.¶
-Want-Content-Digest
and Want-Repr-Digest
are of type Dictionary
-where each:¶
value is an Integer
(Section 3.3.1 of [STRUCTURED-FIELDS])
-that conveys an ascending, relative, weighted preference.
-It must be in the range 0 to 10 inclusive.
-1 is the least preferred, 10 is the most preferred,
-and a value of 0 means "not acceptable".¶
Examples:¶
- -There are a wide variety of hashing algorithms that can be used for the purposes -of integrity. The choice of algorithm depends on several factors such as the -integrity use case, implementation needs or constraints, or application design -and workflows.¶
-An initial set of algorithms will be registered with IANA in the "Hash -Algorithms for HTTP Digest Fields" registry; see -Section 7.2. Additional algorithms can be registered -in accordance with the policies set out in this section.¶
-Each algorithm has a status field, which is intended to provide an aid to -implementation selection.¶
-Algorithms with a status value of "Active" are suitable for many purposes and -it is RECOMMENDED that applications use these algorithms. These can be used in -adversarial situations where hash functions might need to provide resistance to -collision, first-preimage and second-preimage attacks. For adversarial -situations, selecting which of the "Active" algorithms are acceptable will -depend on the level of protection the circumstances demand. -More considerations are presented in Section 6.6.¶
-Algorithms with a status value of "Deprecated" either provide none of these -properties, or are known to be weak (see [NO-MD5] and [NO-SHA]). These -algorithms MAY be used to preserve integrity against corruption, but MUST NOT be -used in a potentially adversarial setting; for example, when signing Integrity -fields' values for authenticity. Permitting the use of these algorithms can help -some applications, for example, those that previously used [RFC3230], are -migrating to this specification (Appendix E), and have existing stored -collections of computed digest values avoid undue operational overhead caused by -recomputation using other more-secure algorithms. Such applications are not -exempt from the requirements in this section. Furthermore, applications without -such legacy or history ought to follow the guidance for using algorithms with -the status value "Active".¶
-Discussion of algorithm agility is presented in Section 6.6.¶
-Registration requests for the "Hash Algorithms for HTTP Digest Fields" registry -use the Specification Required policy (Section 4.6 of [RFC8126]). Requests -should use the following template:¶
-Algorithm Key: the Structured Fields key value used in
-Content-Digest
, Repr-Digest
, Want-Content-Digest
, or Want-Repr-Digest
- field Dictionary member keys¶
Status: the status of the algorithm. The options are:¶
- -Description: a short description of the algorithm¶
-Reference(s): pointer(s) to the primary document(s) defining the Algorithm -Key and technical details of the algorithm¶
-When reviewing registration requests, the designated expert(s) should pay -attention to the requested status. The status value should reflect -standardization status and the broad opinion of relevant interest groups such as -the IETF or security-related SDOs. The "Active" status is not suitable for an -algorithm that is known to be weak, broken, or experimental. If a registration -request attempts to register such an algorithm as "Active", the designated -expert(s) should suggest an alternative status of "Deprecated" or "Provisional".¶
-When reviewing registration requests, the designated expert(s) cannot use a -status of "Deprecated" or "Provisional" as grounds for rejection.¶
-Requests to update or change the fields in an existing registration are -permitted. For example, this could allow for the transition of an algorithm -status from "Active" to "Deprecated" as the security environment evolves.¶
-This document specifies a data integrity mechanism that protects HTTP -representation data or content, but not HTTP header and trailer fields, from -certain kinds of corruption.¶
-Integrity fields are not intended to be a general protection against malicious tampering with -HTTP messages. -In the absence of additional security mechanisms, -an on-path, malicious actor can remove or recalculate and substitute a digest -value. -This attack can be mitigated by combining mechanisms described in this -document with other approaches such -as transport-layer security or digital signatures (for example, HTTP Message -Signatures [SIGNATURES]).¶
-Integrity fields can help detect representation data or content modification due to implementation errors, -undesired "transforming proxies" (see Section 7.7 of [HTTP]) -or other actions as the data passes across multiple hops or system boundaries. -Even a simple mechanism for end-to-end representation data integrity is valuable -because a user agent can validate that resource retrieval succeeded before handing off to an -HTML parser, video player, etc. for parsing.¶
-Note that using these mechanisms alone does not provide end-to-end integrity of HTTP messages over -multiple hops, since metadata could be manipulated at any stage. Methods to protect -metadata are discussed in Section 6.3.¶
-Digital signatures are widely used together with checksums to provide the -certain identification of the origin of a message [NIST800-32]. Such signatures -can protect one or more HTTP fields and there are additional considerations when -Integrity fields are included in this set.¶
-There are no restrictions placed on the type or format of digital signature that -Integrity fields can be used with. One possible approach is to combine them with -HTTP Message Signatures [SIGNATURES].¶
-Digests explicitly
-depend on the "representation metadata" (e.g., the values of Content-Type
,
-Content-Encoding
etc.). A signature that protects Integrity fields but not other
-"representation metadata" can expose the communication to tampering. For
-example, an actor could manipulate the Content-Type
field-value and cause a
-digest validation failure at the recipient, preventing the application from
-accessing the representation. Such an attack consumes the resources of both
-endpoints. See also Section 3.2.¶
Signatures are likely to be deemed an adversarial setting when applying
-Integrity fields; see Section 5. Repr-Digest
offers an interesting
-possibility when combined with signatures. In the scenario where there is no
-content to send, the digest of an empty string can be included in the message
-and, if signed, can help the recipient detect if content was added either as a
-result of accident or purposeful manipulation. The opposite scenario is also
-supported; including an Integrity field for content, and signing it, can help a
-recipient detect where the content was removed.¶
Any mangling of Integrity fields, including digests' de-duplication -or combining different field values (see Section 5.2 of [HTTP]) -might affect signature validation.¶
-Before sending Integrity fields in a trailer section, the sender -should consider that intermediaries are explicitly allowed to drop any trailer -(see Section 6.5.2 of [HTTP]).¶
-When Integrity fields are used in a trailer section, the field-values are received after the content. -Eager processing of content before the trailer section prevents digest validation, possibly leading to -processing of invalid data.¶
-One of the benefits of using Integrity fields in a trailer section is that it -allows hashing of bytes as they are sent. However, it is possible to -design a hashing algorithm that requires processing of content in such a way -that would negate these benefits. For example, Merkle Integrity Content Encoding -[I-D.thomson-http-mice] requires content to be processed in reverse order. -This means the complete data needs to be available, which means there is -negligible processing difference in sending an Integrity field in a header or -trailer section.¶
-Content coding mechanisms can support different encoding parameters, meaning that the same input content can produce different outputs. For example, GZIP supports multiple compression levels. Such encoding parameters are generally not communicated as representation metadata. For instance, different compression levels would all use the same "Content-Encoding: gzip" field. Other examples include where encoding relies on nonces or timestamps, such as the aes128gcm content coding defined in [RFC8188].¶
-Since it is possible for there to be variation within content coding, the checksum conveyed by the integrity fields cannot be used to provide a proof of integrity "at rest" -unless the whole content is persisted.¶
-The security properties of hashing algorithms are not fixed. -Algorithm Agility (see [RFC7696]) is achieved by providing implementations with flexibility -to choose hashing algorithms from the IANA Hash Algorithms for HTTP Digest Fields registry; see -Section 7.2.¶
-Transition from weak algorithms is supported
-by negotiation of hashing algorithm using Want-Content-Digest
or Want-Repr-Digest
(see Section 4)
-or by sending multiple digests from which the receiver chooses.
-A receiver that depends on a digest for security will be vulnerable
-to attacks on the weakest algorithm it is willing to accept.
-Endpoints are advised that sending multiple values consumes resources,
-which may be wasted if the receiver ignores them (see Section 3).¶
While algorithm agility allows the migration to stronger algorithms -it does not prevent the use of weaker algorithms. -Integrity fields do not provide any mitigations for downgrade or substitution -attacks (see Section 1 of [RFC6211]) of the hashing algorithm. -To protect against such attacks, endpoints could restrict their set of supported algorithms -to stronger ones and protect the fields value by using TLS and/or digital signatures.¶
-Integrity fields validation consumes computational resources. -In order to avoid resource exhaustion, implementations can restrict -validation of the algorithm types, number of validations, or the size of content. -In these cases, skipping validation entirely or ignoring validation failure of a more-preferred algorithm -leaves the possibility of a downgrade attack (see Section 6.6).¶
-IANA is asked to update the -"Hypertext Transfer Protocol (HTTP) Field Name Registry" registry -([HTTP]) according to the table below:¶
-Field Name | -Status | -Reference | -
---|---|---|
Content-Digest | -permanent | -- Section 2 of this document | -
Repr-Digest | -permanent | -- Section 3 of this document | -
Want-Content-Digest | -permanent | -- Section 4 of this document | -
Want-Repr-Digest | -permanent | -- Section 4 of this document | -
Digest | -obsoleted | -- [RFC3230], Section 1.3 of this document | -
Want-Digest | -obsoleted | -- [RFC3230], Section 1.3 of this document | -
IANA is requested to create the new "Hash Algorithms for HTTP Digest Fields" -registry at https://www.iana.org/assignments/http-digest-hash-alg/ and -populate it with the entries in Table 2. The procedure for -new registrations is provided in Section 5.¶
-Algorithm Key | -Status | -Description | -Reference(s) | -
---|---|---|---|
sha-512 | -Active | -The SHA-512 algorithm. | -- [RFC6234], [RFC4648], this document. | -
sha-256 | -Active | -The SHA-256 algorithm. | -- [RFC6234], [RFC4648], this document. | -
md5 | -Deprecated | -The MD5 algorithm. It is vulnerable to collision attacks; see [NO-MD5] and [CMU-836068] - | -- [RFC1321], [RFC4648], this document. | -
sha | -Deprecated | -The SHA-1 algorithm. It is vulnerable to collision attacks; see [NO-SHA] and [IACR-2020-014] - | -- [RFC3174], [RFC4648], [RFC6234] this document. | -
unixsum | -Deprecated | -The algorithm used by the UNIX "sum" command. | -- [RFC4648], [RFC6234], [UNIX], this document. | -
unixcksum | -Deprecated | -The algorithm used by the UNIX "cksum" command. | -- [RFC4648], [RFC6234], [UNIX], this document. | -
adler | -Deprecated | -The ADLER32 algorithm. | -- [RFC1950], this document. | -
crc32c | -Deprecated | -The CRC32c algorithm. | -- [RFC9260] appendix A, this document. | -
IANA is requested to deprecate the "Hypertext Transfer Protocol (HTTP) Digest -Algorithm Values" registry at -https://www.iana.org/assignments/http-dig-alg/http-dig-alg.xhtml and replace the note on this registry with the following text:¶
-"This registry is deprecated since it lists the algorithms that can be used -with the Digest and Want-Digest fields defined in -[RFC3230], which has been obsoleted by -[rfc-to-be-this-document]. While registration is not closed, new registrations -are encouraged to use the [Hash Algorithms for HTTP Digest -Fields]https://www.iana.org/assignments/http-digest-hash-alg/ registry -instead."¶
-This section following examples show how representation metadata, content -transformations, and method impacts on the message and content. These examples a -not exhaustive.¶
-Unless otherwise indicated, the examples are based on the JSON object {"hello":
-"world"}
followed by an LF. When the content contains non-printable characters
-(e.g., when it is encoded) it is shown as a sequence of hex-encoded bytes.¶
Consider a client that wishes to upload a JSON object using the PUT method. It -could do this using the application/json content type without any content -coding.¶
-However, the use of content coding is quite common. The client could also upload
-the same data with a gzip coding (Section 8.4.1.3 of [HTTP]). Note that in
-this case, the Content-Length
contains a larger value due to the coding
-overheads.¶
Sending the gzip coded data without indicating it via Content-Encoding
means
-that the content is malformed. In this case, the server can reply with an error.¶
A Range-Request affects the transferred message content. In this example, the
-client is accessing the resource at /entries/1234
, which is the JSON object
-{"hello": "world"}
followed by an LF. However, the client has indicated a
-preferred content coding and a specific byte range.¶
The server satisfies the client request by responding with a partial -representation (equivalent to the first 10 of the JSON object displayed in whole -in Figure 2).¶
-Aside from content coding or range requests, the method can also affect the -transferred message content. For example, the response to a HEAD request does -not carry content but in this example case does include a Content-Length; see -Section 8.6 of [HTTP].¶
-Finally, the semantics of a response might decouple the target URI
-from the enclosed representation. In the example below, the client issues a POST
-request directed to /authors/
but the response includes a Content-Location
-header field that indicates the enclosed representation refers to the
-resource available at /authors/123
. Note that Content-Length
is not sent
-in this example.¶
The following examples demonstrate interactions where a server responds with a
-Content-Digest
or Repr-Digest
fields even though the client did not solicit one using
-Want-Content-Digest
or Want-Repr-Digest
.¶
Some examples include JSON objects in the content. -For presentation purposes, objects that fit completely within the line-length limits -are presented on a single line using compact notation with no leading space. -Objects that would exceed line-length limits are presented across multiple lines -(one line per key-value pair) with 2 spaces of leading indentation.¶
-Checksum mechanisms defined in this document are media-type agnostic
-and do not provide canonicalization algorithms for specific formats.
-Examples are calculated inclusive of any space.
-While examples can include both fields,
-Content-Digest
and Repr-Digest
can be returned independently.¶
In this example, the message content conveys complete representation data.
-This means that in the response, Content-Digest
and Repr-Digest
-are both computed over the JSON object {"hello": "world"}
followed by an LF, and thus have the same value.¶
In this example, a HEAD request is used to retrieve the checksum -of a resource.¶
-The response Content-Digest
field-value is computed on empty content.
-Repr-Digest
is calculated over the JSON object
-{"hello": "world"}
followed by an LF, which is not shown because there is no content.¶
In this example, the client makes a range request and the server responds with -partial content.¶
-In the response message above, note that the
-Repr-Digest
and Content-Digests
are different.
-The Repr-Digest
field-value is calculated across the entire JSON object
-{"hello": "world"}
followed by an LF, and the field is¶
However, since the message content is constrained to bytes 10-18,
-the Content-Digest
field-value is calculated over the
-sequence "world"}
followed by an LF, thus resulting in¶
The request contains a Repr-Digest
field-value calculated on the enclosed
-representation. It also includes an Accept-Encoding: br
header field that advertises the
-client supports Brotli encoding.¶
The response includes a Content-Encoding: br
that indicates the selected
-representation is Brotli-encoded. The Repr-Digest
field-value is therefore
-different compared to the request.¶
For presentation purposes, the response body is displayed as a sequence of -hex-encoded bytes because it contains non-printable characters.¶
-The request Repr-Digest
field-value is calculated on the enclosed content, which
-is the JSON object {"hello": "world"}
followed by an LF¶
The response Repr-Digest
field-value
-depends on the representation metadata header fields, including
-Content-Encoding: br
even when the response does not contain content.¶
The response contains two digest values using different algorithms.¶
-For presentation purposes, the response body is displayed as a sequence of -hex-encoded bytes because it contains non-printable characters.¶
-The request Repr-Digest
field-value is computed on the enclosed representation
-(see Section 3.1), which is the JSON object {"title": "New
-Title"}
followed by an LF.¶
The representation enclosed in the response is a multiline JSON object followed by an LF.
-It refers to the resource identified by
-Content-Location
(see Section 6.4.2 of [HTTP]);
-an application can thus use Repr-Digest
in association with the resource
-referenced by Content-Location
.¶
The request Repr-Digest
field-value is computed on the enclosed representation (see
-Section 3.1), which is the JSON object {"title": "New
-Title"}
followed by an LF.¶
The representation enclosed in the response describes the status of the request,
-so Repr-Digest
is computed on that enclosed representation. It is a multiline
-JSON object followed by an LF.¶
Response Repr-Digest
has no explicit relation with the resource referenced by
-Location
.¶
This case is analogous to a POST request where the target resource reflects the -target URI.¶
-The PATCH request uses the application/merge-patch+json
media type defined in
-[RFC7396]. Repr-Digest
is calculated on the content, which corresponds to the
-patch document and is the JSON object {"title": "New Title"}
followed by an
-LF.¶
The response Repr-Digest
field-value is computed on the complete representation of the patched
-resource. It is a multiline JSON object followed by an LF.¶
Note that a 204 No Content
response without content but with the same
-Repr-Digest
field-value would have been legitimate too.
-In that case, Content-Digest
would have been computed on an empty content.¶
In error responses, the representation data does not necessarily refer to the -target resource. Instead, it refers to the representation of the error.¶
-In the following example, a client sends the same request from Figure 26 to -patch the resource located at /books/123. However, the resource does not exist -and the server generates a 404 response with a body that describes the error in -accordance with [RFC7807].¶
-The response Repr-Digest
field-value is computed on this enclosed representation.
-It is a multiline JSON object followed by an LF.¶
An origin server sends Repr-Digest
as trailer field, so it can calculate digest-value
-while streaming content and thus mitigate resource consumption.
-The Repr-Digest
field-value is the same as in Appendix B.1 because Repr-Digest
is designed to
-be independent of the use of one or more transfer codings (see Section 3).¶
In the response content below, the string "\r\n" represent the bytes CRLF.¶
-The following examples demonstrate interactions where a client solicits a
-Repr-Digest
using Want-Repr-Digest
.
-The behavior of Content-Digest
and Want-Content-Digest
is identical.¶
Some examples include JSON objects in the content. -For presentation purposes, objects that fit completely within the line-length limits -are presented on a single line using compact notation with no leading space. -Objects that would exceed line-length limits are presented across multiple lines -(one line per key-value pair) with 2 spaces of leading indentation.¶
-Checksum mechanisms described in this document are media-type agnostic -and do not provide canonicalization algorithms for specific formats. -Examples are calculated inclusive of any space.¶
-The client requests a digest, preferring "sha". The server is free to reply with -"sha-256" anyway.¶
-The client requests a "sha" digest because that is the only algorithm it -supports. The server is not obliged to produce a response containing a "sha" -digest, it instead uses a different algorithm.¶
-Appendix C.2 is an example where a server ignores -the client's preferred digest algorithm. -Alternatively a server can also reject -the request and return a response with -error status code such as 4xx or 5xx. -This specification does not prescribe -any requirement on status code selection; -the follow example illustrates one possible -option.¶
-In this example, the client requests a "sha" Repr-Digest
, and the server returns an
-error with problem details [RFC7807] contained in the content. The problem
-details contain a list of the hashing algorithms that the server supports. This
-is purely an example, this specification does not define any format or
-requirements for such content.¶
This section shows examples of digest values for different hashing algorithms.
-The input value is the JSON object {"hello": "world"}
. The digest values are
-each produced by running the relevant hashing algorithm over the input and
-running the output bytes through Byte Sequence
serialization; see Section 4.1.8 of [STRUCTURED-FIELDS].¶
-NOTE: '\' line wrapping per RFC 8792 - -sha-512 - :WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+TaPm+\ - AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: - -sha-256 - :X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=: - -md5 - :Sd/dVLAcvNLSq16eXua5uQ==: - -sha - :07CavjDP4u3/TungoUHJO/Wzr4c=: - -unixsum - :GQU=: - -unixcksum - :7zsHAA==: - -adler - :OZkGFw==: - -crc32c - :Q3lHIA==: -¶ -
HTTP digests are computed by applying a hashing algorithm to input data. -RFC 3230 defined the input data as an "instance", a term it also defined. -The concept of instance has since been superseded by the HTTP semantic term "representation". -It is understood that some implementations of RFC 3230 -mistook "instance" to mean HTTP content. -Using content for the Digest field is an error -that leads to interoperability problems between peers that implement RFC 3230.¶
-RFC 3230 was only ever intended -to use what HTTP now defines as selected representation data. -The semantic concept of digest and representation are explained -alongside the definition of the Repr-Digest field (Section 3).¶
-While the syntax of Digest and Repr-Digest are different, -the considerations and examples this document gives for Repr-Digest -apply equally to Digest because they operate on the same input data; -see Sections 3.1, 6 and 6.3.¶
-RFC 3230 could never communicate -the digest of HTTP message content in the Digest field; -Content-Digest now provides that capability.¶
-RFC 3230 allowed algorithms to define their output encoding format for use with -the Digest field. This resulted in a mix of formats such as base64, hex or -decimal. By virtue of using Structured fields, Content-Digest and Repr-Digest -use only a single encoding format. Further explanation and examples are provided in Appendix D.¶
-This document is based on ideas from [RFC3230], so thanks -to Jeff Mogul and Arthur Van Hoff for their great work. -The original idea of refreshing RFC3230 arose from an interesting -discussion with Mark Nottingham, Jeffrey Yasskin, and Martin Thomson when reviewing -the MICE content coding.¶
-Thanks to Julian Reschke for his valuable contributions to this document, -and to the following contributors that have helped improve this specification by reporting bugs, -asking smart questions, drafting or reviewing text, and evaluating open issues: -Mike Bishop, -Brian Campbell, -Matthew Kerwin, -James Manger, -Tommy Pauly, -Sean Turner, -Justin Richer, -and Erik Wilde.¶
-This section is to be removed before publishing as an RFC.¶
-How can I generate and validate the digest values, computed over the JSON object
-{"hello": "world"}
followed by an LF, shown in the examples throughout this
-document?¶
The following python3 code can be used to generate digests for JSON objects -using SHA algorithms for a range of encodings. Note that these are formatted as -base64. This function could be adapted to other algorithms and should take into -account their specific formatting rules.¶
--import base64, json, hashlib, brotli, logging -log = logging.getLogger() - -def digest_bytes(bytes_, algorithm=hashlib.sha256): - checksum_bytes = algorithm(bytes_).digest() - log.warning("Log bytes: \n[%r]", bytes_) - return base64.encodebytes(checksum_bytes).strip() - -def digest(bytes_, encoding=lambda x: x, algorithm=hashlib.sha256): - content_encoded = encoding(bytes_) - return digest_bytes(content_encoded, algorithm) - - -bytes_ = b'{"hello": "world"}\n' - -print("Encoding | hashing algorithm | digest-value") -print("Identity | sha256 |", digest(bytes_)) -# Encoding | hashing algorithm | digest-value -# Identity | sha256 | RK/0qy18MlBSVnWgjwz6lZEWjP/lF5HF9bvEF8FabDg= - -print("Encoding | hashing algorithm | digest-value") -print("Brotli | sha256 |", digest(bytes_, encoding=brotli.compress)) -# Encoding | hashing algorithm | digest-value -# Brotli | sha256 | d435Qo+nKZ+gLcUHn7GQtQ72hiBVAgqoLsZnZPiTGPk= - -print("Encoding | hashing algorithm | digest-value") -print("Identity | sha512 |", digest(bytes_, algorithm=hashlib.sha512)) -print("Brotli | sha512 |", digest(bytes_, algorithm=hashlib.sha512, - encoding=brotli.compress)) -# Encoding | hashing algorithm | digest-value -# Identity | sha512 |b'YMAam51Jz/jOATT6/zvHrLVgOYTGFy1d6GJiOHTohq4yP' -# '+pgk4vf2aCsyRZOtw8MjkM7iw7yZ/WkppmM44T3qg==' - -# Brotli | sha512 | b'db7fdBbgZMgX1Wb2MjA8zZj+rSNgfmDCEEXM8qLWfpfoNY' -# '0sCpHAzZbj09X1/7HAb7Od5Qfto4QpuBsFbUO3dQ==' - -¶ -
This section is to be removed before publishing as an RFC.¶
-Be clearer that applications can enforce additional requirements wrt digest¶
-Change algorithm status names: s/standard/active, s/insecure/deprecated¶
-Remove "reserved" algorithm status¶
-Provide clear guidance about the use of standard or deprecated algorithms¶
-Editorial or minor changes¶
-Editorial or minor changes¶
-Editorial or minor changes¶
-Editorial or minor changes¶
-Remove id-sha-256 and id-sha-512 from the list of supported algorithms #855¶
-Deprecate SHA-1 #1154¶
-Avoid id-* with encrypted content¶
-Digest is independent of MESSAGING and HTTP/1.1 is not normative #1215¶
-Identity is not a valid field value for content-encoding #1223¶
-Mention trailers #1157¶
-Reference httpbis-semantics #1156¶
-Add contentMD5 as an obsoleted digest-algorithm #1249¶
-Use lowercase digest-algorithms names in the doc and in the digest-algorithm IANA table.¶
-Align title with document name¶
-Add id-sha-* algorithm examples #880¶
-Deprecate MD5¶
-Obsolete ADLER-32 but don't forbid it #828¶
-Update CRC32C value in IANA table #828¶
-Use when acting on resources (POST, PATCH) #853¶
-Added Relationship with SRI, draft Use Cases #868, #971¶
-Warn about the implications of Content-Location
¶
Internet-Draft | -HTTP Message Signatures | -January 2024 | -
Backman, et al. | -Expires 27 July 2024 | -[Page] | -
This document describes a mechanism for creating, encoding, and verifying digital signatures or message authentication codes over components of an HTTP message. This mechanism supports use cases where the full HTTP message may not be known to the signer, and where the message may be transformed (e.g., by intermediaries) before reaching the verifier. -This document also describes a means for requesting that a signature be applied to a subsequent HTTP message in an ongoing HTTP exchange.¶
-This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/signatures.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-Message integrity and authenticity are security properties that are critical to the secure operation of many HTTP applications. -Application developers typically rely on the transport layer to provide these properties, by operating their application over [TLS]. However, TLS only guarantees these properties over a single TLS connection, and the path between client and application may be composed of multiple independent TLS connections (for example, if the application is hosted behind a TLS-terminating gateway or if the client is behind a TLS Inspection appliance). In such cases, TLS cannot guarantee end-to-end message integrity or authenticity between the client and application. Additionally, some operating environments present obstacles that make it impractical to use TLS (such as presentation of client certificates from a browser), or to use features necessary to provide message authenticity. Furthermore, some applications require the binding of a higher-level application-specific key to the HTTP message, separate from any TLS certificates in use. Consequently, while TLS can meet message integrity and authenticity needs for many HTTP-based applications, it is not a universal solution.¶
-Additionally, many applications need to be able to generate and verify signatures despite incomplete knowledge of the HTTP message as seen on the wire, due to the use of libraries, proxies, or application frameworks that alter or hide portions of the message from the application at the time of signing or verification. These applications need a means to protect the parts of the message that are most relevant to the application without having to violate layering and abstraction.¶
-Finally, object-based signature mechanisms such as [JWS] require the intact conveyance of the exact information that was signed. When applying such technologies to an HTTP message, elements of the HTTP message need to be duplicated in the object payload either directly or through inclusion of a hash. This practice introduces complexity since the repeated information needs to be carefully checked for consistency when the signature is verified.¶
-This document defines a mechanism for providing end-to-end integrity and authenticity for components of an HTTP message by use of a detached signature on HTTP messages. The mechanism allows applications to create digital signatures or message authentication codes (MACs) over only the components of the message that are meaningful and appropriate for the application. Strict canonicalization rules ensure that the verifier can verify the signature even if the message has been transformed in many of the ways permitted by HTTP.¶
-The signing mechanism described in this document consists of three parts:¶
-A common nomenclature and canonicalization rule set for the different protocol elements and other components of HTTP messages, used to create the signature base. (Section 2)¶
-Algorithms for generating and verifying signatures over HTTP message components using this signature base through application of cryptographic primitives. (Section 3)¶
-A mechanism for attaching a signature and related metadata to an HTTP message, and for parsing attached signatures and metadata from HTTP messages. To facilitate this, this document defines the "Signature-Input" and "Signature" fields. (Section 4)¶
-This document also provides a mechanism for negotiation the use of signatures in one or more subsequent messages via the "Accept-Signature" field (Section 5). This optional negotiation mechanism can be used along with opportunistic or application-driven message signatures by either party.¶
-The mechanisms defined in this document are important tools that can be used to an overall security mechanism for an application. This toolkit provides some powerful capabilities, but does not sufficient in creating an overall security story. In particular, the requirements in Section 1.4 and the security considerations in Section 7 are of high importance to all implementors of this specification. For example, this specification does not define a means to directly cover HTTP message content (defined in Section 6.4 of [HTTP]), but relies on the [DIGEST] specification to provide a hash of the message content, as discussed in Section 7.2.8.¶
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", -"MAY", and "OPTIONAL" in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here.¶
-The terms "HTTP message", "HTTP request", "HTTP response", -"target URI", "gateway", "header field", "intermediary", "request target", -"trailer field", "sender", "method", and "recipient" are used as defined in [HTTP].¶
-For brevity, the term "signature" on its own is used in this document to refer to both digital signatures (which use asymmetric cryptography) and keyed MACs (which use symmetric cryptography). Similarly, the verb "sign" refers to the generation of either a digital signature or keyed MAC over a given signature base. The qualified term "digital signature" refers specifically to the output of an asymmetric cryptographic signing operation.¶
-This document uses the following terminology from Section 3 of [STRUCTURED-FIELDS] -to specify data types: List, Inner List, Dictionary, Item, String, Integer, Byte Sequence, and Boolean.¶
-This document defines several string constructions using [ABNF] and uses the following ABNF rules: VCHAR
, SP
, DQUOTE
, LF
. This document uses the following ABNF rules from [STRUCTURED-FIELDS]: sf-string
, inner-list
, parameters
. This document uses the following ABNF rules from [HTTP] and [HTTP/1.1]: field-content
, obs-fold
, obs-text
.¶
In addition to those listed above, this document uses the following terms:¶
-A digital signature or keyed MAC that covers one or more portions of an HTTP message. Note that a given HTTP Message can contain multiple HTTP Message Signatures.¶
-The entity that is generating or has generated an HTTP Message Signature. Note that multiple entities can act as signers and apply separate HTTP Message Signatures to a given HTTP Message.¶
-An entity that is verifying or has verified an HTTP Message Signature against an HTTP Message. Note that an HTTP Message Signature may be verified multiple times, potentially by different entities.¶
-A portion of an HTTP message that is capable of being covered by an HTTP Message Signature.¶
-An HTTP Message Component derived from the HTTP message through the use of a specified algorithm or process. See Section 2.2.¶
-A string that identifies an HTTP Message Component's source, such as a field name or derived component name.¶
-The combination of an HTTP Message Component Name and any parameters that uniquely identifies a specific HTTP Message Component in respect to a particular HTTP Message Signature and the HTTP Message it applies to.¶
-The value associated with a given component identifier within the context of a particular HTTP Message. Component values are derived from the HTTP Message and are usually subject to a canonicalization process.¶
-An ordered set of HTTP message component identifiers for fields (Section 2.1) and derived components (Section 2.2) that indicates the set of message components covered by the signature, never including the @signature-params
identifier itself. The order of this set is preserved and communicated between the signer and verifier to facilitate reconstruction of the signature base.¶
The sequence of bytes generated by the signer and verifier using the covered components set and the HTTP Message. The signature base is processed by the cryptographic algorithm to produce or verify the HTTP Message Signature.¶
-A cryptographic algorithm that describes the signing and verification process for the signature, defined in terms of the HTTP_SIGN
and HTTP_VERIFY
primitives described in Section 3.3.¶
The key material required to create or verify the signature. The key material is often identified with an explicit key identifier, allowing the signer to indicate to the verifier which key was used.¶
-A timestamp representing the point in time that the signature was generated, as asserted by the signer.¶
-A timestamp representing the point in time after which the signature should no longer be accepted by the verifier, as asserted by the signer.¶
-The HTTP message to which an HTTP Message Signature is applied.¶
-The data source from which the HTTP Message Component Values are drawn. The context includes the target message and any additional information the signer or verifier might have, such as the full target URI of a request or the related request message for a response.¶
-The term "Unix timestamp" refers to what Section 4.16 of [POSIX.1] calls "Seconds Since the Epoch".¶
-This document contains non-normative examples of partial and complete HTTP messages. Some examples use a single trailing backslash \
to indicate line wrapping for long values, as per [RFC8792]. The \
character and leading spaces on wrapped lines are not part of the value.¶
HTTP permits and sometimes requires intermediaries to transform messages in a variety of ways. This can result in a recipient receiving a message that is not bitwise-equivalent to the message that was originally sent. In such a case, the recipient will be unable to verify integrity protections over the raw bytes of the sender's HTTP message, as verifying digital signatures or MACs requires both signer and verifier to have the exact same signature base. Since the exact raw bytes of the message cannot be relied upon as a reliable source for a signature base, the signer and verifier have to independently create the signature base from their respective versions of the message, via a mechanism that is resilient to safe changes that do not alter the meaning of the message.¶
-For a variety of reasons, it is impractical to strictly define what constitutes a safe change versus an unsafe one. Applications use HTTP in a wide variety of ways and may disagree on whether a particular piece of information in a message (e.g., the message content, the method, or a particular header field) is relevant. Thus, a general purpose solution needs to provide signers with some degree of control over which message components are signed.¶
-HTTP applications may be running in environments that do not provide complete access to or control over HTTP messages (such as a web browser's JavaScript environment), or may be using libraries that abstract away the details of the protocol (such as the Java HTTPClient library). These applications need to be able to generate and verify signatures despite incomplete knowledge of the HTTP message.¶
-As mentioned earlier, HTTP explicitly permits and in some cases requires implementations to transform messages in a variety of ways. Implementations are required to tolerate many of these transformations. What follows is a non-normative and non-exhaustive list of transformations that could occur under HTTP, provided as context:¶
-Re-ordering of fields with different field names (Section 5.3 of [HTTP]).¶
-Combination of fields with the same field name (Section 5.2 of [HTTP]).¶
-Removal of fields listed in the Connection header field (Section 7.6.1 of [HTTP]).¶
-Addition of fields that indicate control options (Section 7.6.1 of [HTTP]).¶
-Addition or removal of a transfer coding (Section 7.7 of [HTTP]).¶
-Addition of fields such as Via
(Section 7.6.3 of [HTTP]) and Forwarded
(Section 4 of [RFC7239]).¶
Conversion between different versions of the HTTP protocol (e.g., HTTP/1.x to HTTP/2, or vice-versa).¶
-Changes in casing (e.g., "Origin" to "origin") of any case-insensitive components such as field names, request URI scheme, or host.¶
-Changes to the request target and authority that when applied together do not - result in a change to the message's target URI, as defined in Section 7.1 of [HTTP].¶
-Additionally, there are some transformations that are either deprecated or otherwise not allowed, but still could occur in the wild. These transformations can still be handled without breaking the signature, and include things such as:¶
-Use, addition, or removal of leading or trailing whitespace in a field value.¶
-Use, addition, or removal of obs-fold
in field values (Section 5.2 of [HTTP/1.1]).¶
We can identify these types of transformations as ones that should not prevent signature verification, even when performed on message components covered by the signature. Additionally, all changes to components not covered by the signature should not prevent signature verification.¶
-Some examples of these kinds of transformations, and the effect they have on the message signature, are found in Appendix B.4.¶
-Other transformations, such as parsing and re-serializing the field values of a covered component or changing the value of a derived component, can cause a signature to no longer validate against a target message. Applications of this specification need to take care to ensure that the transformations expected by the application are adequately handled by the choice of covered components.¶
-HTTP Message Signatures are designed to be a general-purpose tool applicable in a wide variety of circumstances and applications. In order to properly and safely apply HTTP Message Signatures, an application or profile of this specification MUST specify at least all of the following items:¶
-The set of component identifiers (Section 2) and signature parameters (Section 2.3) that are expected and required to be included in the covered components list. For example, an authorization protocol could mandate that the Authorization field be covered to protect the authorization credentials and mandate the signature parameters contain a created
parameter, while an API expecting semantically relevant HTTP message content could require the Content-Digest field defined in [DIGEST] to be present and covered as well as mandate a value for tag
that is specific to the API being protected.¶
The expected structured field types ([STRUCTURED-FIELDS]) of any required or expected covered component fields or parameters.¶
-A means of retrieving the key material used to verify the signature. An application will usually use the keyid
parameter of the signature parameters (Section 2.3) and define rules for resolving a key from there, though the appropriate key could be known from other means such as pre-registration of a signer's key.¶
The set of allowable signature algorithms to be used by signers and accepted by verifiers.¶
-A means of determining that the signature algorithm used to verify the signature is appropriate for the key material and context of the message. For example, the process could use the alg
parameter of the signature parameters (Section 2.3) to state the algorithm explicitly, derive the algorithm from the key material, or use some pre-configured algorithm agreed upon by the signer and verifier.¶
A means of determining that a given key and algorithm used for a signature are appropriate for the context of the message. For example, a server expecting only ECDSA signatures should know to reject any RSA signatures, or a server expecting asymmetric cryptography should know to reject any symmetric cryptography.¶
-A means of determining the context for derivation of message components from an HTTP message and its application context. While this is normally the target HTTP message itself, the context could include additional information known to the application through configuration, such as an external host name.¶
-If binding between a request and response is needed using the mechanism in Section 2.4, all elements of the request and response message that would be required to provide properties of such a binding.¶
-The error messages and codes that are returned from the verifier to the signer when the signature is invalid, the key material is inappropriate, the validity time window is out of specification, a component value cannot be calculated, or any other errors in the signature verification process. For example, if a signature is being used as an authentication mechanism, an HTTP status code of 401 Unauthorized or 403 Forbidden could be appropriate. If the response is from an HTTP API, a response with an HTTP status code of 400 Bad Request could include details as described in [RFC7807], such as an indicator that the wrong key material was used.¶
-When choosing these parameters, an application of HTTP message signatures has to ensure that the verifier will have access to all required information needed to re-create the signature base. For example, a server behind a reverse proxy would need to know the original request URI to make use of the derived component @target-uri
, even though the apparent target URI would be changed by the reverse proxy (see also Section 7.4.3). Additionally, an application using signatures in responses would need to ensure that clients receiving signed responses have access to all the signed portions of the message, including any portions of the request that were signed by the server using the related-response parameter.¶
The details of this kind of profiling are the purview of the application and outside the scope of this specification, however some additional considerations are discussed in Section 7. In particular, when choosing the required set of component identifiers, care has to be taken to make sure that the coverage is sufficient for the application, as discussed in Section 7.2.1 and Section 7.2.8. This specification defines only part of a full security system for an application. When building a complete security system based on this tool, it is important to perform a security analysis of the entire system of which HTTP Message Signatures is a part. Historical systems, such as [AWS-SIGv4], can provide inspiration and examples of how to apply similar mechanisms to an application, though review of such historical systems does not negate the need for a security analysis of an application of HTTP Message Signatures.¶
-In order to allow signers and verifiers to establish which components are covered by a signature, this document defines component identifiers for components covered by an HTTP Message Signature, a set of rules for deriving and canonicalizing the values associated with these component identifiers from the HTTP Message, and the means for combining these canonicalized values into a signature base.¶
-The signature context for deriving these values MUST be accessible to both the signer and the verifier of the message. The context MUST be the same across all components in a given signature. For example, it would be an error to use the raw query string for the @query
derived component but combined query and form parameters for the @query-param
derived component. For more considerations of the message component context, see Section 7.4.3.¶
A component identifier is composed of a component name and any parameters associated with that name. Each component name is either an HTTP field name (Section 2.1) or a registered derived component name (Section 2.2). The possible parameters for a component identifier are dependent on the component identifier, and the HTTP Signature Component Parameters registry cataloging all possible parameters is defined in Section 6.5.¶
-Within a single list of covered components, each component identifier MUST occur only once. One component identifier is distinct from another if the component name differs, or if any of the parameters differ for the same component name. Multiple component identifiers having the same component name MAY be included if they have parameters that make them distinct, such as "foo";bar
and "foo";baz
. The order of parameters MUST be preserved when processing a component identifier (such as when parsing during verification), but the order of parameters is not significant when comparing two component identifiers for equality checks. That is to say, "foo";bar;baz
cannot be in the same message as "foo";baz;bar
, since these two component identifiers are equivalent, but a system processing one form is not allowed to transform it into the other form.¶
The component value associated with a component identifier is defined by the identifier itself. Component values MUST NOT contain newline (\n
) characters. Some HTTP message components can undergo transformations that change the bitwise value without altering the meaning of the component's value (for example, when combining field values). Message component values therefore need to be canonicalized before they are signed, to ensure that a signature can be verified despite such intermediary transformations. This document defines rules for each component identifier that transform the identifier's associated component value into such a canonical form.¶
The following sections define component identifier names, their parameters, their associated values, and the canonicalization rules for their values. The method for combining message components into the signature base is defined in Section 2.5.¶
-The component name for an HTTP field is the lowercased form of its field name as defined in Section 5.1 of [HTTP]. While HTTP field names are case-insensitive, implementations MUST use lowercased field names (e.g., content-type
, date
, etag
) when using them as component names.¶
The component value for an HTTP field is the field value for the named field as defined in Section 5.5 of [HTTP]. The field value MUST be taken from the named header field of the target message unless this behavior is overridden by additional parameters and rules, such as the req
and tr
flags, below. For most fields, the field value is an ASCII string as recommended by [HTTP], and the component value is exactly that string. Other encodings could exist in some implementations, and all non-ASCII field values MUST be encoded to ASCII before being added to the signature base. The bs
parameter defined in Section 2.1.3 provides a method for wrapping such problematic field values.¶
Unless overridden by additional parameters and rules, HTTP field values MUST be combined into a single value as defined in Section 5.2 of [HTTP] to create the component value. Specifically, HTTP fields sent as multiple fields MUST be combined by concatenating the values using a single comma and a single space as a separator ("," + " "). Note that intermediaries are allowed to combine values of HTTP fields with any amount of whitespace between the commas, and if this behavior is not accounted for by the verifier, the signature can fail since the signer and verifier will see a different component value in their respective signature bases. For robustness, it is RECOMMENDED that signed messages include only a single instance of any field covered under the signature, particularly with the value for any list-based fields serialized using the algorithm below. This approach increases the chances of the field value remaining untouched through intermediaries. Where that approach is not possible and multiple instances of a field need to be sent separately, it is RECOMMENDED that signers and verifiers process any list-based fields taking all individual field values and combining them based on the strict algorithm below, to counter possible intermediary behavior. When the field in question is a structured field of type List or Dictionary, this effect can be accomplished more directly by requiring the strict structured field serialization of the field value, as described in Section 2.1.1.¶
-Note that some HTTP fields, such as Set-Cookie ([COOKIE]), do not follow a syntax that allows for combination of field values in this manner (such that the combined output is unambiguous from multiple inputs). Even though the component value is never parsed by the message signature process and used only as part of the signature base in Section 2.5, caution needs to be taken when including such fields in signatures since the combined value could be ambiguous. The bs
parameter defined in Section 2.1.3 provides a method for wrapping such problematic fields. See Section 7.5.6 for more discussion of this issue.¶
If the correctly combined value is not directly available for a given field by an implementation, the following algorithm will produce canonicalized results for list-based fields:¶
-Create an ordered list of the field values of each instance of the field in the message, in the order that they occur (or will occur) in the message.¶
-Strip leading and trailing whitespace from each item in the list. Note that since HTTP field values are not allowed to contain leading and trailing whitespace, this will be a no-op in a compliant implementation.¶
-Remove any obsolete line-folding within the line and replace it with a single space (" "), as discussed in Section 5.2 of [HTTP/1.1]. Note that this behavior is specific to HTTP/1.1 and does not apply to other versions of the HTTP specification which do not allow internal line folding.¶
-Concatenate the list of values together with a single comma (",") and a single space (" ") between each item.¶
-The resulting string is the component value for the field.¶
-Note that some HTTP fields have values with multiple valid serializations that have equivalent semantics, such as allow case-insensitive values that intermediaries could change. Applications signing and processing such fields MUST consider how to handle the values of such fields to ensure that the signer and verifier can derive the same value, as discussed in Section 7.5.2.¶
-Following are non-normative examples of component values for header fields, given the following example HTTP message fragment:¶
- -The following example shows the component values for these example header fields, presented using the signature base format defined in Section 2.5:¶
--"host": www.example.com -"date": Tue, 20 Apr 2021 02:07:56 GMT -"x-ows-header": Leading and trailing whitespace. -"x-obs-fold-header": Obsolete line folding. -"cache-control": max-age=60, must-revalidate -"example-dict": a=1, b=2;x=1;y=2, c=(a b c) -¶ -
Empty HTTP fields can also be signed when present in a message. The canonicalized value is the empty string. This means that the following empty header, with (SP) indicating a single trailing space character before the empty field value:¶
--X-Empty-Header:(SP) -¶ -
Is serialized by the signature base generation algorithm (Section 2.5) with an empty string value following the colon and space added after the content identifier.¶
--"x-empty-header":(SP) -¶ -
Any HTTP field component identifiers MAY have the following parameters in specific circumstances, each described in detail in their own sections:¶
-sf
A boolean flag indicating that the component value is serialized using strict encoding -of the structured field value (Section 2.1.1).¶
-key
A string parameter used to select a single member value from a Dictionary structured field (Section 2.1.2).¶
-bs
A boolean flag indicating that individual field values are encoded using Byte Sequence data structures before being combined into the component value (Section 2.1.3).¶
-req
A boolean flag for signed responses indicating that the component value is derived from the request that triggered this response message and not from the response message directly. Note that this parameter can also be applied to any derived component identifiers that target the request (Section 2.4).¶
-tr
A boolean flag indicating that the field value is taken from the trailers of the message as defined in Section 6.5 of [HTTP]. If this flag is absent, the field value is taken from the headers of the message as defined in Section 6.3 of [HTTP] (Section 2.1.4).¶
-Multiple parameters MAY be specified together, though some combinations are redundant or incompatible. For example, the sf
parameter's functionality is already covered when the key
parameter is used on a dictionary item, since key
requires strict serialization of the value. The bs
parameter, which requires the raw bytes of the field values from the message, is not compatible with use of the sf
or key
parameters, which require the parsed data structures of the field values after combination.¶
Additional parameters can be defined in the HTTP Signature Component Parameters registry established in Section 6.5.¶
-If the value of an HTTP field is known by the application to be a structured field type (as defined in [STRUCTURED-FIELDS] or its extensions or updates), and the expected type of the structured field is known, the signer MAY include the sf
parameter in the component identifier.
-If this parameter is included with a component identifier, the HTTP field value MUST be serialized using the formal serialization rules specified in Section 4 of [STRUCTURED-FIELDS] (or the
-applicable formal serialization section of its extensions or updates) applicable to
-the type of the HTTP field. Note that this process
-will replace any optional internal whitespace with a single space character, among other potential transformations of the value.¶
If multiple field values occur within a message, these values MUST be combined into a single List or Dictionary structure before serialization.¶
-If the application does not know the type of the field, or the application does not know how to serialize the type of the field, the use of this flag will produce an error. As a consequence, the signer can only reliably sign fields using this flag when the verifier's system knows the type as well.¶
-For example, the following dictionary field is a valid serialization:¶
- -If included in the signature base without parameters, its value would be:¶
--"example-dict": a=1, b=2;x=1;y=2, c=(a b c) -¶ -
However, if the sf
parameter is added, the value is re-serialized as follows:¶
-"example-dict";sf: a=1, b=2;x=1;y=2, c=(a b c) -¶ -
The resulting string is used as the component value in Section 2.1.¶
-If a given field is known by the application to be a Dictionary structured field, an individual member in the value of that Dictionary is identified by using the parameter key
and the Dictionary member key as a String value.¶
If multiple field values occur within a message, these values MUST be combined into a single Dictionary structure before serialization.¶
-An individual member value of a Dictionary Structured Field is canonicalized by applying the serialization algorithm described in Section 4.1.2 of [STRUCTURED-FIELDS] on the member_value
and its parameters, not including the dictionary key itself. Specifically, the value is serialized as an Item or Inner List (the two possible values of a Dictionary member), with all parameters and possible sub-fields serialized using the strict serialization rules defined in Section 4 of [STRUCTURED-FIELDS] (or the applicable section of its extensions or updates).¶
Each parameterized key for a given field MUST NOT appear more than once in the signature base. Parameterized keys MAY appear in any order in the signature base, regardless of the order they occur in the source Dictionary.¶
-If a Dictionary key is named as a covered component but it does not occur in the Dictionary, this MUST cause an error in the signature base generation.¶
-Following are non-normative examples of canonicalized values for Dictionary structured field members given the following example header field, whose value is known by the application to be a Dictionary:¶
- -The following example shows canonicalized values for different component identifiers of this field, presented using the signature base format discussed in Section 2.5:¶
--"example-dict";key="a": 1 -"example-dict";key="d": ?1 -"example-dict";key="b": 2;x=1;y=2 -"example-dict";key="c": (a b c) -¶ -
Note that the value for key="c"
has been re-serialized according to the strict member_value
algorithm, and the value for key="d"
has been serialized as a Boolean value.¶
If the value of the HTTP field in question is known by the application to cause problems with serialization, particularly with the combination of multiple values into a single line as discussed in Section 7.5.6, the signer SHOULD include the bs
parameter in a component identifier to indicate the values of the field need to be wrapped as binary structures before being combined.¶
If this parameter is included with a component identifier, the component value MUST be calculated using the following algorithm:¶
-Let the input be the ordered set of values for a field, in the order they appear in the message.¶
-Create an empty List for accumulating processed field values.¶
-For each field value in the set:¶
-Strip leading and trailing whitespace from the field value. Note that since HTTP field values are not allowed to contain leading and trailing whitespace, this will be a no-op in a compliant implementation.¶
-Remove any obsolete line-folding within the line and replace it with a single space (" "), as discussed in Section 5.2 of [HTTP/1.1]. Note that this behavior is specific to [HTTP/1.1] and does not apply to other versions of the HTTP specification.¶
-Encode the bytes of the resulting field value as a Byte Sequence. Note that most fields are restricted to ASCII characters, but other octets could be included in the value in some implementations.¶
-Add the Byte Sequence to the List accumulator.¶
-The intermediate result is a List of Byte Sequence values.¶
-Follow the strict serialization of a List as described in Section 4.1.1 of [STRUCTURED-FIELDS] and return this output.¶
-For example, the following field with internal commas prevents the distinct field values from being safely combined:¶
- -In our example, the same field can be sent with a semantically different single value:¶
- -Both of these versions are treated differently by the application. However, if included in the signature base without parameters, the component value would be the same in both cases:¶
--"example-header": value, with, lots, of, commas -¶ -
However, if the bs
parameter is added, the two separate instances are encoded and serialized as follows:¶
-"example-header";bs: :dmFsdWUsIHdpdGgsIGxvdHM=:, :b2YsIGNvbW1hcw==: -¶ -
For the single-instance field above, the encoding with the bs
parameter is:¶
-"example-header";bs: :dmFsdWUsIHdpdGgsIGxvdHMsIG9mLCBjb21tYXM=: -¶ -
This component value is distinct from the multiple-instance field above, preventing a collision which could potentially be exploited.¶
-If the signer wants to include a trailer field in the signature, the signer MUST include the tr
boolean parameter to indicate the value MUST be taken from the trailer fields and not from the header fields.¶
For example, given the following message:¶
- -The signer decides to add both the Trailer header field as well as the Expires trailer to the signature base, along with the status code derived component:¶
--"@status": 200 -"trailer": Expires -"expires";tr: Wed, 9 Nov 2022 07:28:00 GMT -¶ -
If a field is available as both a header and trailer in a message, both values MAY be signed, but the values MUST be signed separately. The values of header fields and trailer fields of the same name MUST NOT be combined for purposes of the signature.¶
-Since trailer fields could be merged into the header fields or dropped entirely by intermediaries as per Section 6.5.1 of [HTTP], it is NOT RECOMMENDED to include trailers in the signature unless the signer knows that the verifier will have access to the values of the trailers as sent.¶
-In addition to HTTP fields, there are a number of different components that can be derived from the control data, signature context, or other aspects of the HTTP message being signed. Such derived components can be included in the signature base by defining a component name, possible parameters, message target, and the derivation method for its component value.¶
-Derived component names MUST start with the "at" @
character. This differentiates derived component names from HTTP field names, which cannot contain the @
character as per Section 5.1 of [HTTP]. Processors of HTTP Message Signatures MUST treat derived component names separately from field names, as discussed in Section 7.5.1.¶
This specification defines the following derived components:¶
-The method used for a request. (Section 2.2.1)¶
-The full target URI for a request. (Section 2.2.2)¶
-The authority of the target URI for a request. (Section 2.2.3)¶
-The scheme of the target URI for a request. (Section 2.2.4)¶
-The request target. (Section 2.2.5)¶
-The absolute path portion of the target URI for a request. (Section 2.2.6)¶
-The query portion of the target URI for a request. (Section 2.2.7)¶
-A parsed and encoded query parameter of the target URI for a request. (Section 2.2.8)¶
-The status code for a response. (Section 2.2.9)¶
-Additional derived component names are defined in the HTTP Signature Derived Component Names Registry. (Section 6.4)¶
-Derived component values are taken from the context of the target message for the signature. This context includes information about the message itself, such as its control data, as well as any additional state and context held by the signer or verifier. In particular, when signing a response, the signer can include any derived components from the originating request by using the request-response parameter (Section 2.4).¶
-Values derived from and results applied to an HTTP request message as described in Section 3.4 of [HTTP]. If the target message of the signature is a response, using the req
parameter allows a request-targeted derived component to be included in the signature (see Section 2.4).¶
Values derived from and results applied to an HTTP response message as described in Section 3.4 of [HTTP].¶
-A derived component definition MUST define all target message types to which it can be applied.¶
-Derived component values MUST be limited to printable characters and spaces and MUST NOT contain any newline characters. Derived component values MUST NOT start or end with whitespace characters.¶
-The @method
derived component refers to the HTTP method of a request message. The component value is canonicalized by taking the value of the method as a string. Note that the method name is case-sensitive as per [HTTP], Section 9.1. While conventionally standardized method names are uppercase [ASCII], no transformation to the input method value's case is performed.¶
For example, the following request message:¶
- -Would result in the following @method
component value:¶
-POST -¶ -
And the following signature base line:¶
--"@method": POST -¶ -
The @target-uri
derived component refers to the target URI of a request message. The component value is the full absolute target URI of the request, potentially assembled from all available parts including the authority and request target as described in [HTTP], Section 7.1.¶
For example, the following message sent over HTTPS:¶
- -Would result in the following @target-uri
component value:¶
-https://www.example.com/path?param=value -¶ -
And the following signature base line:¶
--"@target-uri": https://www.example.com/path?param=value -¶ -
The @scheme
derived component refers to the scheme of the target URL of the HTTP request message. The component value is the scheme as a lowercase string as defined in [HTTP], Section 4.2.
-While the scheme itself is case-insensitive, it MUST be normalized to lowercase for
-inclusion in the signature base.¶
For example, the following request message requested over plain HTTP:¶
- -Would result in the following @scheme
component value:¶
-http -¶ -
And the following signature base line:¶
--"@scheme": http -¶ -
The @request-target
derived component refers to the full request target of the HTTP request message,
-as defined in [HTTP], Section 7.1. The component value of the request target can take different forms,
-depending on the type of request, as described below.¶
For HTTP/1.1, the component value is equivalent to the request target -portion of the request line. However, this value is more difficult to reliably construct in -other versions of HTTP. Therefore, it is NOT RECOMMENDED that this component be used -when versions of HTTP other than 1.1 might be in use.¶
-The origin form value is combination of the absolute path and query components of the request URL. For example, the following request message:¶
- -Would result in the following @request-target
component value:¶
-/path?param=value -¶ -
And the following signature base line:¶
--"@request-target": /path?param=value -¶ -
The following request to an HTTP proxy with the absolute-form value, containing the fully qualified target URI:¶
- -Would result in the following @request-target
component value:¶
-https://www.example.com/path?param=value -¶ -
And the following signature base line:¶
--"@request-target": https://www.example.com/path?param=value -¶ -
The following CONNECT request with an authority-form value, containing the host and port of the target:¶
- -Would result in the following @request-target
component value:¶
-www.example.com:80 -¶ -
And the following signature base line:¶
--"@request-target": www.example.com:80 -¶ -
The following OPTIONS request message with the asterisk-form value, containing a single asterisk *
character:¶
Would result in the following @request-target
component value:¶
-* -¶ -
And the following signature base line:¶
--"@request-target": * -¶ -
The @path
derived component refers to the target path of the HTTP request message. The component value is the absolute path of the request target defined by [URI], with no query component and no trailing ?
character. The value is normalized according to the rules in [HTTP], Section 4.2.3. Namely, an empty path string is normalized as a single slash /
character. Path components are represented by their values before decoding any percent-encoded octets, as described in the simple string comparison rules in Section 6.2.1 of [URI].¶
For example, the following request message:¶
- -Would result in the following @path
component value:¶
-/path -¶ -
And the following signature base line:¶
--"@path": /path -¶ -
The @query
derived component refers to the query component of the HTTP request message. The component value is the entire normalized query string defined by [URI], including the leading ?
character. The value is read using the simple string comparison rules in Section 6.2.1 of [URI]. Namely, percent-encoded octets are not decoded.¶
For example, the following request message:¶
- -Would result in the following @query
component value:¶
-?param=value&foo=bar&baz=bat%2Dman -¶ -
And the following signature base line:¶
--"@query": ?param=value&foo=bar&baz=bat%2Dman -¶ -
The following request message:¶
- -Would result in the following @query
component value:¶
-?queryString -¶ -
And the following signature base line:¶
--"@query": ?queryString -¶ -
Just like including an empty path component, the signer can include an empty query component to indicate that this component is not used in the message. If the query string is absent from the request message, the component value is the leading ?
character alone:¶
-? -¶ -
Resulting in the following signature base line:¶
--"@query": ? -¶ -
If a request target URI uses HTML form parameters in the query string as defined in the "application/x-www-form-urlencoded" section of [HTMLURL],
-the @query-param
derived component allows addressing of individual query parameters. The query parameters MUST be parsed according to the "application/x-www-form-urlencoded parsing" section of [HTMLURL], resulting in a list of (nameString
, valueString
) tuples.
-The REQUIRED name
parameter of each component identifier contains the encoded nameString
of a single query parameter as a String value.
-The component value of a single named parameter is the encoded valueString
of that single query parameter.
-Several different named query parameters MAY be included in the covered components.
-Single named parameters MAY occur in any order in the covered components, regardless of the order they occur in the query string.¶
The value of the name
parameter and the component value of a single named parameter are calculated by the following process:¶
Parse the nameString
or valueString
of the named query parameter defined by the "application/x-www-form-urlencoded parsing" section of [HTMLURL], which is the value after percent-encoded octets are decoded.¶
Encode the nameString
or valueString
using the "percent-encode after encoding" process defined by the "application/x-www-form-urlencoded serializing" section of [HTMLURL], which results in an [ASCII] string.¶
Output the ASCII string,¶
-Note that the component value does not include any leading ?
characters, equals sign =
, or separating &
characters.
-Named query parameters with an empty valueString
have an empty string as the component value. Note that due to inconsistencies in implementations, some query parameter parsing libraries drop such empty values.¶
If a query parameter is named as a covered component but it does not occur in the query parameters, this MUST cause an error in the signature base generation.¶
-For example for the following request:¶
- -Indicating the baz
, qux
and param
named query parameters would result in the following @query-param
component values:¶
baz: batman
¶
qux: an empty string¶
-param: value
¶
And the following signature base lines, with (SP) indicating a single trailing space character before the empty component value:¶
--"@query-param";name="baz": batman -"@query-param";name="qux":(SP) -"@query-param";name="param": value -¶ -
This derived component has some limitations. Specifically, the algorithm in [HTMLURL] only supports query parameters using percent-escaped UTF-8 encoding. Other encodings are not supported.
-Additionally, multiple instances of a named parameter are not reliably supported in the wild. If a parameter name occurs multiple times in a request, the named query parameter MUST NOT be included. If multiple parameters are common within an application, it is RECOMMENDED to sign the entire query string using the @query
component identifier defined in Section 2.2.7.¶
The encoding process allows query parameters that include newlines or other problematic characters in their values, or with alternative encodings such as using the plus character to represent spaces. For the query parameters in this message:¶
- -The resulting values are encoded as follows:¶
--"@query-param";name="var": this%20is%20a%20big%0Amultiline%20value -"@query-param";name="bar": with%20plus%20whitespace -"@query-param";name="fa%C3%A7ade%22%3A%20": something -¶ -
If the encoding were not applied, the resultant values would be:¶
--"@query-param";name="var": this is a big -multiline value -"@query-param";name="bar": with plus whitespace -"@query-param";name="façade\": ": something -¶ -
This base string contains characters that violate the constraints on component names and values, and is therefore invalid.¶
-The @status
derived component refers to the three-digit numeric HTTP status code of a response message as defined in [HTTP], Section 15. The component value is the serialized three-digit integer of the HTTP status code, with no descriptive text.¶
For example, the following response message:¶
- -Would result in the following @status
component value:¶
-200 -¶ -
And the following signature base line:¶
--"@status": 200 -¶ -
The @status
component identifier MUST NOT be used in a request message.¶
HTTP Message Signatures have metadata properties that provide information regarding the signature's generation and verification, consisting of the ordered set of covered components and the ordered set of parameters including a timestamp of signature creation, identifiers for verification key material, and other utilities. This metadata is represented by a special message component in the signature base for signature parameters, and it is treated slightly differently from other message components. Specifically, the signature parameters message component is REQUIRED as the last line of the signature base (Section 2.5), and the component identifier MUST NOT be enumerated within the set of covered components for any signature, including itself.¶
-The signature parameters component name is @signature-params
.¶
The signature parameters component value is the serialization of the signature parameters for this signature, including the covered components ordered set with all associated parameters. These parameters include any of the following:¶
-created
: Creation time as an Integer UNIX timestamp value. Sub-second precision is not supported. Inclusion of this parameter is RECOMMENDED.¶
expires
: Expiration time as an Integer UNIX timestamp value. Sub-second precision is not supported.¶
nonce
: A random unique value generated for this signature as a String value.¶
alg
: The HTTP message signature algorithm from the HTTP Signature Algorithms registry, as a String value.¶
keyid
: The identifier for the key material as a String value.¶
tag
: An application-specific tag for the signature as a String value. This value is used by applications to help identify signatures relevant for specific applications or protocols.¶
Additional parameters can be defined in the HTTP Signature Metadata Parameters Registry (Section 6.3). Note that there is no general ordering to the parameters, but once an ordering is chosen for a given set of parameters, it cannot be changed without altering the signature parameters value.¶
-The signature parameters component value is serialized as a parameterized Inner List using the rules in Section 4 of [STRUCTURED-FIELDS] as follows:¶
-Let the output be an empty string.¶
-Determine an order for the component identifiers of the covered components, not including the @signature-params
component identifier itself. Once this order is chosen, it cannot be changed. This order MUST be the same order as used in creating the signature base (Section 2.5).¶
Serialize the component identifiers of the covered components, including all parameters, as an ordered Inner List of String values according to Section 4.1.1.1 of [STRUCTURED-FIELDS] and append this to the output. Note that the component identifiers can include their own parameters, and these parameters are ordered sets. Once an order is chosen for a component's parameters, the order cannot be changed.¶
-Determine an order for any signature parameters. Once this order is chosen, it cannot be changed.¶
-Append the parameters to the Inner List in order according to Section 4.1.1.2 of [STRUCTURED-FIELDS], - skipping parameters that are not available or not used for this message signature.¶
-The output contains the signature parameters component value.¶
-Note that the Inner List serialization from Section 4.1.1.1 of [STRUCTURED-FIELDS] is used for the covered component value instead of the List serialization from Section 4.1.1 of [STRUCTURED-FIELDS] -in order to facilitate parallelism with this value's inclusion in the Signature-Input field, -as discussed in Section 4.1.¶
-This example shows the serialized component value for the parameters of an example message signature:¶
--NOTE: '\' line wrapping per RFC 8792 - -("@target-uri" "@authority" "date" "cache-control")\ - ;keyid="test-key-rsa-pss";alg="rsa-pss-sha512";\ - created=1618884475;expires=1618884775 -¶ -
Note that an HTTP message could contain multiple signatures (Section 4.3), but only the signature parameters used for a single signature are included in a given signature parameters entry.¶
-When a request message results in a signed response message, the signer can include portions of the request message in the signature base by adding the req
parameter to the component identifier.¶
req
A boolean flag indicating that the component value is derived from the request that triggered this response message and not from the response message directly.¶
-This parameter can be applied to both HTTP fields and derived components that target the request, with the same semantics. The component value for a message component using this parameter is calculated in the same manner as it is normally, but data is pulled from the request message instead of the target response message to which the signature is applied.¶
-Note that the same component name MAY be included with and without the req
parameter in a single signature base, indicating the same named component from both the request and response message, respectively.¶
The req
parameter MAY be combined with other parameters as appropriate for the component identifier, such as the key
parameter for a dictionary field.¶
For example, when serving a response for this request:¶
- -This would result in the following unsigned response message:¶
- -The server signs the response with its own key, including the @status
code and several header fields in the covered components. While this covers a reasonable amount of the response for this application, the server additionally includes several components derived from the original request message that triggered this response. In this example, the server includes the method, authority, path, and content digest from the request in the covered components of the response. The Content-Digest for both the request and the response are included under the response signature. For the application in this example, the query is deemed not to be relevant to the response and is therefore not covered. Other applications would make different decisions based on application needs as discussed in Section 1.4.¶
The signature base for this example is:¶
--NOTE: '\' line wrapping per RFC 8792 - -"@status": 503 -"content-digest": sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObf\ - wnHJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: -"content-type": application/json -"@authority";req: example.com -"@method";req: POST -"@path";req: /foo -"content-digest";req: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A\ - 2svX+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: -"@signature-params": ("@status" "content-digest" "content-type" \ - "@authority";req "@method";req "@path";req "content-digest";req)\ - ;created=1618884479;keyid="test-key-ecc-p256" -¶ -
The signed response message is:¶
- -Note that the ECDSA algorithm in use here is non-deterministic, meaning a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly-generated signature values are not expected to match the example. See Section 7.3.5.¶
-Since the component values from the request are not repeated in the response message, the requester MUST keep the original message component values around long enough to validate the signature of the response that uses this component identifier parameter. In most cases, this means the requester needs to keep the original request message around, since the signer could choose to include any portions of the request in its response, according to the needs of the application. Since it is possible for an intermediary to alter a request message before it is processed by the server, applications need to take care not to sign such altered values as the client would not be able to validate the resulting signature.¶
-It is additionally possible for a server to create a signed response in response to a signed request. For example, this signed request:¶
--NOTE: '\' line wrapping per RFC 8792 - -POST /foo?param=Value&Pet=dog HTTP/1.1 -Host: example.com -Date: Tue, 20 Apr 2021 02:07:55 GMT -Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ - aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: -Content-Type: application/json -Content-Length: 18 -Signature-Input: sig1=("@method" "@authority" "@path" "@query" \ - "content-digest" "content-type" "content-length")\ - ;created=1618884475;keyid="test-key-rsa-pss" -Signature: sig1=:e8UJ5wMiRaonlth5ERtE8GIiEH7Akcr493nQ07VPNo6y3qvjdK\ - t0fo8VHO8xXDjmtYoatGYBGJVlMfIp06eVMEyNW2I4vN7XDAz7m5v1108vGzaDljr\ - d0H8+SJ28g7bzn6h2xeL/8q+qUwahWA/JmC8aOC9iVnwbOKCc0WSrLgWQwTY6VLp4\ - 2Qt7jjhYT5W7/wCvfK9A1VmHH1lJXsV873Z6hpxesd50PSmO+xaNeYvDLvVdZlhtw\ - 5PCtUYzKjHqwmaQ6DEuM8udRjYsoNqp2xZKcuCO1nKc0V3RjpqMZLuuyVbHDAbCzr\ - 0pg2d2VM/OC33JAU7meEjjaNz+d7LWPg==: - -{"hello": "world"} -¶ -
The server could choose to sign portions of this response, including several portions of the request resulting in this signature base:¶
--NOTE: '\' line wrapping per RFC 8792 - -"@status": 503 -"content-digest": sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObf\ - wnHJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==: -"content-type": application/json -"@authority";req: example.com -"@method";req: POST -"@path";req: /foo -"@query";req: ?param=Value&Pet=dog -"content-digest";req: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A\ - 2svX+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: -"content-type";req: application/json -"content-length";req: 18 -"@signature-params": ("@status" "content-digest" "content-type" \ - "@authority";req "@method";req "@path";req "@query";req \ - "content-digest";req "content-type";req "content-length";req)\ - ;created=1618884479;keyid="test-key-ecc-p256" -¶ -
And the following signed response:¶
- -Note that the ECDSA algorithm in use here is non-deterministic, meaning a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly-generated signature values are not expected to match the example. See Section 7.3.5.¶
-Applications signing a response to a signed request SHOULD sign all of the components of the request signature value to provide sufficient coverage and protection against a class of collision attacks, as discussed in Section 7.3.7. The server in this example has included all components listed in the Signature-Input of the client's signature on the request in the response signature, in addition to components of the response.¶
-While it is syntactically possible to include the Signature and Signature-Input fields of the request message in the signature components of a response a message using this mechanism, this practice is NOT RECOMMENDED. This is because signatures of signatures do not provide transitive coverage of covered components as one might expect and the practice is susceptible to several attacks as discussed in Section 7.3.7. An application that needs to signal successful processing or receipt of a signature would need to carefully specify alternative mechanisms for sending such a signal securely.¶
-The response signature can only ever cover what is included in the request message when using this flag. Consequently, if an application needs to include the message content of the request under the signature of its response, the client needs to include a means for covering that content, such as a Content-Digest field. See the discussion in Section 7.2.8 for more information.¶
-The req
parameter MUST NOT be used for any component in a signature that targets a request message.¶
The signature base is a [ASCII] string containing the canonicalized HTTP message components covered by the signature. The input to the signature base creation algorithm is the ordered set of covered component identifiers and their associated values, along with any additional signature parameters discussed in Section 2.3.¶
-Component identifiers are serialized using the strict serialization rules defined by [STRUCTURED-FIELDS], Section 4.
-The component identifier has a component name, which is a String Item value serialized using the sf-string
ABNF rule. The component identifier MAY also include defined parameters which are serialized using the parameters
ABNF rule. The signature parameters line defined in Section 2.3 follows this same pattern, but the component identifier is a String Item with a fixed value and no parameters, and the component value is always an Inner List with optional parameters.¶
Note that this means the serialization of the component name itself is encased in double quotes, with parameters following as a semicolon-separated list, such as "cache-control"
, "@authority"
, "@signature-params"
, or "example-dictionary";key="foo"
.¶
The output is the ordered set of bytes that form the signature base, which conforms to the following ABNF:¶
--signature-base = *( signature-base-line LF ) signature-params-line -signature-base-line = component-identifier ":" SP - ( derived-component-value / *field-content ) - ; no obs-fold nor obs-text -component-identifier = component-name parameters -component-name = sf-string -derived-component-value = *( VCHAR / SP ) -signature-params-line = DQUOTE "@signature-params" DQUOTE - ":" SP inner-list -¶ -
To create the signature base, the signer or verifier concatenates together entries for each component identifier in the signature's covered components (including their parameters) using the following algorithm. All errors produced as described immediately MUST fail the algorithm with no signature output base output.¶
-Let the output be an empty string.¶
-For each message component item in the covered components set (in order):¶
-If the component identifier (including its parameters) has already been added to the signature base, produce an error.¶
-Append the component identifier for the covered component serialized according to the component-identifier
ABNF rule. Note that this serialization places the component name in double quotes and appends any parameters outside of the quotes.¶
Append a single colon :
¶
Append a single space " "¶
-Determine the component value for the component identifier.¶
-If the component identifier has a parameter that is not understood, produce an error.¶
-If the component identifier has parameters that are mutually incompatible with one another, such as bs
and sf
, produce an error.¶
If the component identifier contains the req
parameter and the target message is a request, produce an error.¶
If the component identifier contains the req
parameter and the target message is a response, the context for the component value is the related request message of the target response message. Otherwise, the context for the component value is the target message.¶
If the component name starts with an "at" character (@
), derive the component's value from the message according to the specific rules defined for the derived component, as in Section 2.2, including processing of any known valid parameters. If the derived component name is unknown or the value cannot be derived, produce an error.¶
If the component name does not start with an "at" character (@
), canonicalize the HTTP field value as described in Section 2.1, including processing of any known valid parameters. If the field cannot be found in the message, or the value cannot be obtained in the context, produce an error.¶
Append the covered component's canonicalized component value.¶
-Append a single newline \n
¶
Append the signature parameters component (Section 2.3) according to the signature-params-line
rule as follows:¶
Append the component identifier for the signature parameters serialized according to the component-identifier
rule, i.e. the exact value "@signature-params"
(including double quotes)¶
Append a single colon :
¶
Append a single space " "¶
-Append the signature parameters' canonicalized component value as defined in Section 2.3, i.e. an Inner List structured field value with parameters¶
-Produce an error if the output string contains any non-ASCII ([ASCII]) characters.¶
-Return the output string.¶
-If covered components reference a component identifier that cannot be resolved to a component value in the message, the implementation MUST produce an error and not create a signature base. Such situations include, but are not limited to:¶
-The signer or verifier does not understand the derived component name.¶
-The component name identifies a field that is not present in the message or whose value is malformed.¶
-The component identifier includes a parameter that is unknown or does not apply to the component identifier to which it is attached.¶
-The component identifier indicates that a structured field serialization is used (via the sf
parameter), but the field in question is known to not be a structured field or the type of structured field is not known to the implementation.¶
The component identifier is a dictionary member identifier that references a field that is not present in the message, is not a Dictionary Structured Field, or whose value is malformed.¶
-The component identifier is a dictionary member identifier or a named query parameter identifier that references a member that is not present in the component value, or whose value is malformed. E.g., the identifier is "example-dict";key="c"
and the value of the Example-Dict header field is a=1, b=2
, which does not have the c
value.¶
In the following non-normative example, the HTTP message being signed is the following request:¶
- -The covered components consist of the @method
, @authority
, and @path
derived components followed by the Content-Digest
, Content-Length
, and Content-Type
HTTP header fields, in order. The signature parameters consist of a creation timestamp of 1618884473
and a key identifier of test-key-rsa-pss
. Note that no explicit alg
parameter is given here since the verifier is known by the application to use the RSA PSS algorithm based on the identified key. The signature base for this message with these parameters is:¶
Note that the example signature base here, or anywhere else within this specification, does not include the final newline that ends the displayed example.¶
-An HTTP Message Signature is a signature over a string generated from a subset of the components of an HTTP message in addition to metadata about the signature itself. When successfully verified against an HTTP message, an HTTP Message Signature provides cryptographic proof that the message is semantically equivalent to the message for which the signature was generated, with respect to the subset of message components that was signed.¶
-Creation of an HTTP message signature is a process that takes as its input the signature context (including the target message) and the requirements for the application. The output is a signature value and set of signature parameters that can be communicated to the verifier by adding them to the message.¶
-In order to create a signature, a signer MUST follow the following algorithm:¶
-The signer chooses an HTTP signature algorithm and key material for signing from the set of potential signing algorithms. - The set of potential algorithms is determined by the application and is out of scope for this document. - The signer MUST choose key material that is appropriate - for the signature's algorithm, and that conforms to any requirements defined by the algorithm, such as key size or format. The - mechanism by which the signer chooses the algorithm and key material is out of scope for this document.¶
-The signer sets the signature's creation time to the current time.¶
-If applicable, the signer sets the signature's expiration time property to the time at which the signature is to expire. The expiration is a hint to the verifier, expressing the time at which the signer is no longer willing to vouch for the signature. An appropriate expiration length, and the processing requirements of this parameter, are application-specific.¶
-The signer creates an ordered set of component identifiers representing the message components to be covered by the signature, and attaches signature metadata parameters to this set. The serialized value of this is later used as the value of the Signature-Input field as described in Section 4.1.¶
-Once an order of covered components is chosen, the order MUST NOT change for the life of the signature.¶
-Each covered component identifier MUST be either an HTTP field in the signature context Section 2.1 or a derived component listed in Section 2.2 or the HTTP Signature Derived Component Names registry.¶
-Signers of a request SHOULD include some or all of the message control data in the covered components, such as the @method
, @authority
, @target-uri
, or some combination thereof.¶
Signers SHOULD include the created
signature metadata parameter to indicate when the signature was created.¶
The @signature-params
derived component identifier MUST NOT be listed in the list of covered component identifiers. The derived component is required to always be the last line in the signature base, ensuring that a signature always covers its own metadata and the metadata cannot be substituted.¶
Further guidance on what to include in this set and in what order is out of scope for this document.¶
-The signer creates the signature base using these parameters and the signature base creation algorithm. (Section 2.5)¶
-The signer uses the HTTP_SIGN
primitive function to sign the signature base with the chosen signing algorithm using the key material chosen by the signer. The HTTP_SIGN
primitive and several concrete applications of signing algorithms are defined in Section 3.3.¶
The byte array output of the signature function is the HTTP message signature output value to be included in the Signature field as defined in Section 4.2.¶
-For example, given the HTTP message and signature parameters in the example in Section 2.5, the example signature base is signed with the test-key-rsa-pss
key in Appendix B.1.2 and the RSA PSS algorithm described in Section 3.3.1, giving the following message signature output value, encoded in Base64:¶
-NOTE: '\' line wrapping per RFC 8792 - -HIbjHC5rS0BYaa9v4QfD4193TORw7u9edguPh0AW3dMq9WImrlFrCGUDih47vAxi4L2\ -YRZ3XMJc1uOKk/J0ZmZ+wcta4nKIgBkKq0rM9hs3CQyxXGxHLMCy8uqK488o+9jrptQ\ -+xFPHK7a9sRL1IXNaagCNN3ZxJsYapFj+JXbmaI5rtAdSfSvzPuBCh+ARHBmWuNo1Uz\ -VVdHXrl8ePL4cccqlazIJdC4QEjrF+Sn4IxBQzTZsL9y9TP5FsZYzHvDqbInkTNigBc\ -E9cKOYNFCn4D/WM7F6TNuZO9EgtzepLWcjTymlHzK7aXq6Am6sfOrpIC49yXjj3ae6H\ -RalVc/g== --
Note that the RSA PSS algorithm in use here is non-deterministic, meaning a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly-generated signature values are not expected to match the example. See Section 7.3.5.¶
-Verification of an HTTP message signature is a process that takes as its input the signature context (including the target message, particularly its Signature and Signature-Input fields) and the requirements for the application. The output of the verification is either a positive verification or an error.¶
-In order to verify a signature, a verifier MUST follow the following algorithm:¶
-Parse the Signature and Signature-Input fields as described in Section 4.1 and Section 4.2, and extract the signatures to be verified.¶
-If there is more than one signature value present, determine which signature should be processed - for this message based on the policy and configuration of the verifier. If an applicable signature is not found, produce an error.¶
-If the chosen Signature value does not have a corresponding Signature-Input value, - produce an error.¶
-Parse the values of the chosen Signature-Input field as a parameterized Inner List to get the ordered list of covered components and the signature parameters for the signature to be verified.¶
-Parse the value of the corresponding Signature field to get the byte array value of the signature - to be verified.¶
-Examine the signature parameters to confirm that the signature meets the requirements described - in this document, as well as any additional requirements defined by the application such as which - message components are required to be covered by the signature. (Section 3.2.1)¶
-Determine the verification key material for this signature. If the key material is known through external - means such as static configuration or external protocol negotiation, the verifier will use that. If the key is - identified in the signature parameters, the verifier will dereference this to appropriate key material to use - with the signature. The verifier has to determine the trustworthiness of the key material for the context - in which the signature is presented. If a key is identified that the verifier does not know, does - not trust for this request, or does not match something preconfigured, the verification MUST fail.¶
-Determine the algorithm to apply for verification:¶
-Start with the set of allowable algorithms known to the application. If any of the following steps selects an algorithm that is not in this set, the signature validation fails.¶
-If the algorithm is known through external means such as static configuration or external protocol - negotiation, the verifier will use this algorithm.¶
-If the algorithm can be determined from the keying material, such as through an algorithm field - on the key value itself, the verifier will use this algorithm.¶
-If the algorithm is explicitly stated in the signature parameters using a value from the - HTTP Signature Algorithms registry, the verifier will use the referenced algorithm.¶
-If the algorithm is specified in more than one location, such as through static configuration - and the algorithm signature parameter, or the algorithm signature parameter and from - the key material itself, the resolved algorithms MUST be the same. If the algorithms are - not the same, the verifier MUST fail the verification.¶
-Use the received HTTP message and the parsed signature parameters to re-create the signature base, using
- the algorithm defined in Section 2.5. The value of the @signature-params
input is
- the value of the Signature-Input field for this signature serialized according to the rules described
- in Section 2.3. Note that this does not include the signature's label from the Signature-Input field.¶
If the key material is appropriate for the algorithm, apply the appropriate HTTP_VERIFY
cryptographic verification algorithm to the signature,
- recalculated signature base, key material, signature value. The HTTP_VERIFY
primitive and several concrete algorithms are defined in
- Section 3.3.¶
The results of the verification algorithm function are the final results of the cryptographic verification function.¶
-If any of the above steps fail or produce an error, the signature validation fails.¶
-For example, verifying the signature with the key sig1
of the following message with the test-key-rsa-pss
key in Appendix B.1.2 and the RSA PSS algorithm described in Section 3.3.1:¶
With the additional requirements that at least the method, authority, path, content-digest, content-length, and content-type be signed, and that the signature creation timestamp is recent enough at the time of verification, the verification passes.¶
-The verification requirements specified in this document are intended as a baseline set of restrictions that are generally applicable to all use cases. Applications using HTTP Message Signatures MAY impose requirements above and beyond those specified by this document, as appropriate for their use case.¶
-Some non-normative examples of additional requirements an application might define are:¶
-Requiring a specific set of header fields to be signed (e.g., Authorization, Digest).¶
-Enforcing a maximum signature age from the time of the created
time stamp.¶
Rejection of signatures past the expiration time in the expires
time stamp. Note that the expiration time is a hint from the signer and that a verifier can always reject a signature ahead of its expiration time.¶
Prohibition of certain signature metadata parameters, such as runtime algorithm signaling with the alg
parameter when the algorithm is determined from the key information.¶
Ensuring successful dereferencing of the keyid
parameter to valid and appropriate key material.¶
Prohibiting the use of certain algorithms, or mandating the use of a specific algorithm.¶
-Requiring keys to be of a certain size (e.g., 2048 bits vs. 1024 bits).¶
-Enforcing uniqueness of the nonce
parameter.¶
Requiring an application-specific value for the tag
parameter.¶
Application-specific requirements are expected and encouraged. When an application defines additional requirements, it MUST enforce them during the signature verification process, and signature verification MUST fail if the signature does not conform to the application's requirements.¶
-Applications MUST enforce the requirements defined in this document. Regardless of use case, applications MUST NOT accept signatures that do not conform to these requirements.¶
-An HTTP Message signature MUST use a cryptographic digital signature or MAC method that is -appropriate for the key material, environment, and needs of the signer and verifier. This specification does not strictly limit the available signature algorithms, and any signature algorithm that meets these basic requirements MAY be used by an application of HTTP message signatures.¶
-Each signing method HTTP_SIGN
takes as its input the signature base defined in Section 2.5 as a byte array (M
), the signing key material
-(Ks
), and outputs the signature output as a byte array (S
):¶
-HTTP_SIGN (M, Ks) -> S -¶ -
Each verification method HTTP_VERIFY
takes as its input the re-generated signature base defined in Section 2.5 as a byte array (M
), the verification key
-material (Kv
), and the presented signature to be verified as a byte array (S
) and outputs the verification result (V
) as a boolean:¶
-HTTP_VERIFY (M, Kv, S) -> V -¶ -
The following sections contain several common signature algorithms and demonstrate how these cryptographic primitives map to the HTTP_SIGN
and HTTP_VERIFY
definitions here. Which method to use can be communicated through the explicit algorithm signature parameter alg
-defined in Section 2.3, by reference to the key material, or through mutual agreement between the signer and verifier. Signature algorithms selected using the alg
parameter MUST use values from the HTTP Signature Algorithms registry (Section 6.2).¶
To sign using this algorithm, the signer applies the RSASSA-PSS-SIGN (K, M)
function defined in [RFC8017] with the signer's private signing key (K
) and
-the signature base (M
) (Section 2.5).
-The mask generation function is MGF1
as specified in [RFC8017] with a hash function of SHA-512 [RFC6234].
-The salt length (sLen
) is 64 bytes.
-The hash function (Hash
) SHA-512 [RFC6234] is applied to the signature base to create
-the digest content to which the digital signature is applied.
-The resulting signed content byte array (S
) is the HTTP message signature output used in Section 3.1.¶
To verify using this algorithm, the verifier applies the RSASSA-PSS-VERIFY ((n, e), M, S)
function [RFC8017] using the public key portion of the verification key material ((n, e)
) and the signature base (M
) re-created as described in Section 3.2.
-The mask generation function is MGF1
as specified in [RFC8017] with a hash function of SHA-512 [RFC6234].
-The salt length (sLen
) is 64 bytes.
-The hash function (Hash
) SHA-512 [RFC6234] is applied to the signature base to create the digest content to which the verification function is applied.
-The verifier extracts the HTTP message signature to be verified (S
) as described in Section 3.2.
-The results of the verification function indicate if the signature presented is valid.¶
Note that the output of RSA PSS algorithms are non-deterministic, and therefore it is not correct to re-calculate a new signature on the signature base and compare the results to an existing signature. Instead, the verification algorithm defined here needs to be used. See Section 7.3.5.¶
-Use of this algorithm can be indicated at runtime using the rsa-pss-sha512
value for the alg
signature parameter.¶
To sign using this algorithm, the signer applies the RSASSA-PKCS1-V1_5-SIGN (K, M)
function defined in [RFC8017] with the signer's private signing key (K
) and
-the signature base (M
) (Section 2.5).
-The hash SHA-256 [RFC6234] is applied to the signature base to create
-the digest content to which the digital signature is applied.
-The resulting signed content byte array (S
) is the HTTP message signature output used in Section 3.1.¶
To verify using this algorithm, the verifier applies the RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S)
function [RFC8017] using the public key portion of the verification key material ((n, e)
) and the signature base (M
) re-created as described in Section 3.2.
-The hash function SHA-256 [RFC6234] is applied to the signature base to create the digest content to which the verification function is applied.
-The verifier extracts the HTTP message signature to be verified (S
) as described in Section 3.2.
-The results of the verification function indicate if the signature presented is valid.¶
Use of this algorithm can be indicated at runtime using the rsa-v1_5-sha256
value for the alg
signature parameter.¶
To sign and verify using this algorithm, the signer applies the HMAC
function [RFC2104] with the shared signing key (K
) and
-the signature base (text
) (Section 2.5).
-The hash function SHA-256 [RFC6234] is applied to the signature base to create the digest content to which the HMAC is applied, giving the signature result.¶
For signing, the resulting value is the HTTP message signature output used in Section 3.1.¶
-For verification, the verifier extracts the HTTP message signature to be verified (S
) as described in Section 3.2.
-The output of the HMAC function is compared bytewise to the value of the HTTP message signature, and the results of the comparison determine the validity of the signature presented.¶
Use of this algorithm can be indicated at runtime using the hmac-sha256
value for the alg
signature parameter.¶
To sign using this algorithm, the signer applies the ECDSA
algorithm defined in [FIPS186-4] using curve P-256 with the signer's private signing key and
-the signature base (Section 2.5).
-The hash SHA-256 [RFC6234] is applied to the signature base to create
-the digest content to which the digital signature is applied, (M
).
-The signature algorithm returns two integer values, r
and s
. These are both encoded as big-endian unsigned integers, zero-padded to 32-octets each. These encoded values are concatenated into a single 64-octet array consisting of the encoded value of r
followed by the encoded value of s
. The resulting concatenation of (r, s)
is byte array of the HTTP message signature output used in Section 3.1.¶
To verify using this algorithm, the verifier applies the ECDSA
algorithm defined in [FIPS186-4] using the public key portion of the verification key material and the signature base re-created as described in Section 3.2.
-The hash function SHA-256 [RFC6234] is applied to the signature base to create the digest content to which the signature verification function is applied, (M
).
-The verifier extracts the HTTP message signature to be verified (S
) as described in Section 3.2. This value is a 64-octet array consisting of the encoded values of r
and s
concatenated in order. These are both encoded in big-endian unsigned integers, zero-padded to 32-octets each. The resulting signature value (r, s)
is used as input to the signature verification function.
-The results of the verification function indicate if the signature presented is valid.¶
Note that the output of ECDSA algorithms are non-deterministic, and therefore it is not correct to re-calculate a new signature on the signature base and compare the results to an existing signature. Instead, the verification algorithm defined here needs to be used. See Section 7.3.5.¶
-Use of this algorithm can be indicated at runtime using the ecdsa-p256-sha256
value for the alg
signature parameter.¶
To sign using this algorithm, the signer applies the ECDSA
algorithm defined in [FIPS186-4] using curve P-384 with the signer's private signing key and
-the signature base (Section 2.5).
-The hash SHA-384 [RFC6234] is applied to the signature base to create
-the digest content to which the digital signature is applied, (M
).
-The signature algorithm returns two integer values, r
and s
. These are both encoded as big-endian unsigned integers, zero-padded to 48-octets each. These encoded values are concatenated into a single 96-octet array consisting of the encoded value of r
followed by the encoded value of s
. The resulting concatenation of (r, s)
is byte array of the HTTP message signature output used in Section 3.1.¶
To verify using this algorithm, the verifier applies the ECDSA
algorithm defined in [FIPS186-4] using the public key portion of the verification key material and the signature base re-created as described in Section 3.2.
-The hash function SHA-384 [RFC6234] is applied to the signature base to create the digest content to which the signature verification function is applied, (M
).
-The verifier extracts the HTTP message signature to be verified (S
) as described in Section 3.2. This value is a 96-octet array consisting of the encoded values of r
and s
concatenated in order. These are both encoded in big-endian unsigned integers, zero-padded to 48-octets each. The resulting signature value (r, s)
is used as input to the signature verification function.
-The results of the verification function indicate if the signature presented is valid.¶
Note that the output of ECDSA algorithms are non-deterministic, and therefore it is not correct to re-calculate a new signature on the signature base and compare the results to an existing signature. Instead, the verification algorithm defined here needs to be used. See Section 7.3.5.¶
-Use of this algorithm can be indicated at runtime using the ecdsa-p384-sha384
value for the alg
signature parameter.¶
To sign using this algorithm, the signer applies the Ed25519
algorithm defined in Section 5.1.6 of [RFC8032] with the signer's private signing key and
-the signature base (Section 2.5).
-The signature base is taken as the input message (M
) with no pre-hash function.
-The signature is a 64-octet concatenation of R
and S
as specified in Section 5.1.6 of [RFC8032], and this is taken as a byte array for the HTTP message signature output used in Section 3.1.¶
To verify using this algorithm, the signer applies the Ed25519
algorithm defined in Section 5.1.7 of [RFC8032] using the public key portion of the verification key material (A
) and the signature base re-created as described in Section 3.2.
-The signature base is taken as the input message (M
) with no pre-hash function.
-The signature to be verified is processed as the 64-octet concatenation of R
and S
as specified in Section 5.1.7 of [RFC8032].
-The results of the verification function indicate if the signature presented is valid.¶
Use of this algorithm can be indicated at runtime using the ed25519
value for the alg
signature parameter.¶
If the signing algorithm is a JOSE signing algorithm from the JSON Web Signature and Encryption Algorithms Registry established by [RFC7518], the -JWS algorithm definition determines the signature and hashing algorithms to apply for both signing and verification.¶
-For both signing and verification, the HTTP messages signature base (Section 2.5) is used as the entire "JWS Signing Input". -The JOSE Header defined in [RFC7517] is not used, and the signature base is not first encoded in Base64 before applying the algorithm. -The output of the JWS signature is taken as a byte array prior to the Base64url encoding used in JOSE.¶
-The JWS algorithm MUST NOT be none
and MUST NOT be any algorithm with a JOSE Implementation Requirement of Prohibited
.¶
JWA algorithm values from the JSON Web Signature and Encryption Algorithms Registry are not included as signature parameters. Typically, the JWS algorithm can be signaled using JSON Web Keys or other mechanisms common to JOSE implementations. In fact, JWA algorithm values are not registered in the HTTP Signature Algorithms registry (Section 6.2), and so the explicit alg
signature parameter is not used at all when using JOSE signing algorithms.¶
HTTP message signatures can be included within an HTTP message via the Signature-Input and Signature fields, both defined within this specification.¶
-The Signature-Input field identifies the covered components and parameters that describe how the signature was generated, while the Signature field contains the signature value. Each field MAY contain multiple labeled values.¶
-An HTTP message signature is identified by a label within an HTTP message. This label MUST be unique within a given HTTP message and MUST be used in both the Signature-Input and Signature fields. The label is chosen by the signer, except where a specific label is dictated by protocol negotiations such as described in Section 5.¶
-An HTTP message signature MUST use both Signature-Input and Signature fields and each field MUST contain the same labels. The presence of a label in one field but not in the other is an error.¶
-The Signature-Input field is a Dictionary structured field (defined in Section 3.2 of [STRUCTURED-FIELDS]) containing the metadata for one or more message signatures generated from components within the HTTP message. Each member describes a single message signature. The member's key is the label that uniquely identifies the message signature within the HTTP message. The member's value is the serialization of the covered components Inner List plus all signature metadata parameters identified by the label.¶
- -To facilitate signature validation, the Signature-Input field value MUST contain the same serialized value used
-in generating the signature base's @signature-params
value defined in Section 2.3. Note that in a structured field value, list order and parameter order have to be preserved.¶
The signer MAY include the Signature-Input field as a trailer to facilitate signing a message after its content has been processed by the signer. However, since intermediaries are allowed to drop trailers as per [HTTP], it is RECOMMENDED that the Signature-Input field be included only as a header to avoid signatures being inadvertently stripped from a message.¶
-Multiple Signature-Input fields MAY be included in a single HTTP message. The signature labels MUST be unique across all field values.¶
-The Signature field is a Dictionary structured field defined in Section 3.2 of [STRUCTURED-FIELDS] containing one or more message signatures generated from the signature context of the target message. The member's key is the label that uniquely identifies the message signature within the HTTP message. The member's value is a Byte Sequence containing the signature value for the message signature identified by the label.¶
- -The signer MAY include the Signature field as a trailer to facilitate signing a message after its content has been processed by the signer. However, since intermediaries are allowed to drop trailers as per [HTTP], it is RECOMMENDED that the Signature field be included only as a header to avoid signatures being inadvertently stripped from a message.¶
-Multiple Signature fields MAY be included in a single HTTP message. The signature labels MUST be unique across all field values.¶
-Multiple distinct signatures MAY be included in a single message. Each distinct signature MUST have a unique label. These multiple signatures could be added all by the same signer or could come from several different signers. For example, a signer may include multiple signatures signing the same message components with different keys or algorithms to support verifiers with different capabilities, or a reverse proxy may include information about the client in fields when forwarding the request to a service host, including a signature over the client's original signature values.¶
-The following non-normative example starts with a signed request from the client. A reverse proxy takes this request and validates the client's signature.¶
- -The proxy then alters the message before forwarding it on to the origin server, changing the target host and adding the Forwarded header field defined in [RFC7239].¶
- -The proxy is in a position to validate the incoming client's signature and make its own statement to the origin server about the nature of the request that it is forwarding by adding its own signature over the new message before passing it along to the origin server. -The proxy also includes all the elements from the original message that are relevant to the origin server's processing. In many cases, the proxy will want to cover all the same components that were covered by the client's signature, which is the case in this example. Note that in this example, the proxy is signing over the new authority value, which it has changed. The proxy also adds the Forwarded header to its own signature value. -The proxy identifies its own key and algorithm and, in this example, includes an expiration for the signature to indicate to downstream systems that the proxy will not vouch for this signed message past this short time window. This results in a signature base of:¶
--NOTE: '\' line wrapping per RFC 8792 - -"@method": POST -"@authority": origin.host.internal.example -"@path": /foo -"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ - +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: -"content-type": application/json -"content-length": 18 -"forwarded": for=192.0.2.123;host=example.com;proto=https -"@signature-params": ("@method" "@authority" "@path" \ - "content-digest" "content-type" "content-length" "forwarded")\ - ;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256"\ - ;expires=1618884540 -¶ -
And a signature output value of:¶
--NOTE: '\' line wrapping per RFC 8792 - -S6ZzPXSdAMOPjN/6KXfXWNO/f7V6cHm7BXYUh3YD/fRad4BCaRZxP+JH+8XY1I6+8Cy\ -+CM5g92iHgxtRPz+MjniOaYmdkDcnL9cCpXJleXsOckpURl49GwiyUpZ10KHgOEe11s\ -x3G2gxI8S0jnxQB+Pu68U9vVcasqOWAEObtNKKZd8tSFu7LB5YAv0RAGhB8tmpv7sFn\ -Im9y+7X5kXQfi8NMaZaA8i2ZHwpBdg7a6CMfwnnrtflzvZdXAsD3LH2TwevU+/PBPv0\ -B6NMNk93wUs/vfJvye+YuI87HU38lZHowtznbLVdp770I6VHR6WfgS9ddzirrswsE1w\ -5o0LV/g== -¶ -
These values are added to the HTTP request message by the proxy. The original signature is included under the identifier sig1
, and the reverse proxy's signature is included under the label proxy_sig
. The proxy uses the key test-key-rsa
to create its signature using the rsa-v1_5-sha256
signature algorithm, while the client's original signature was made using the key id of test-key-rsa-pss
and an RSA PSS signature algorithm.¶
While the proxy could additionally include the client's Signature value and Signature-Input fields from the original message in the new signature's covered components, this practice is NOT RECOMMENDED due to known weaknesses in signing signature values as discussed in Section 7.3.7. The proxy is in a position to validate the client's signature, the changes the proxy makes to the message will invalidate the existing signature when the message is seen by the origin server. In this example, it is possible for the origin server to have additional information in its signature context to account for the change in authority, though this practice requires additional configuration and extra care as discussed in Section 7.4.4. In other applications, the origin server will not be able to verify the original signature itself but will still want to verify that the proxy has done the appropriate validation of the client's signature. An application that needs to signal successful processing or receipt of a signature would need to carefully specify alternative mechanisms for sending such a signal securely.¶
-While a signer is free to attach a signature to a request or response without prompting, it is often desirable for a potential verifier to signal that it expects a signature from a potential signer using the Accept-Signature field.¶
-When the Accept-Signature field is sent in an HTTP request message, the field indicates that the client desires the server to sign the response using the identified parameters, and the target message is the response to this request. All responses from resources that support such signature negotiation SHOULD either be uncacheable or contain a Vary header field that lists Accept-Signature, in order to prevent a cache from returning a response with a signature intended for a different request.¶
-When the Accept-Signature field is used in an HTTP response message, the field indicates that the server desires the client to sign its next request to the server with the identified parameters, and the target message is the client's next request. The client can choose to also continue signing future requests to the same server in the same way.¶
-The target message of an Accept-Signature field MUST include all labeled signatures indicated in the Accept-Header signature, each covering the same identified components of the Accept-Signature field.¶
-The sender of an Accept-Signature field MUST include only identifiers that are appropriate for the type of the target message. For example, if the target message is a request, the covered components can not include the @status
component identifier.¶
The Accept-Signature field is a Dictionary structured field (defined in Section 3.2 of [STRUCTURED-FIELDS]) containing the metadata for one or more requested message signatures to be generated from message components of the target HTTP message. Each member describes a single message signature. The member's key is the label that uniquely identifies the requested message signature within the context of the target HTTP message.¶
-The member's value is the serialization of the desired covered components of the target message, including any allowed component metadata parameters, using the serialization process defined in Section 2.3.¶
- -The list of component identifiers indicates the exact set of component identifiers to be included in the requested signature, including all applicable component parameters.¶
-The signature request MAY include signature metadata parameters that indicate desired behavior for the signer. The following behavior is defined by this specification:¶
-created
: The signer is requested to generate and include a creation time. This parameter has no associated value when sent as a signature request.¶
expires
: The signer is requested to generate and include an expiration time. This parameter has no associated value when sent as a signature request.¶
nonce
: The signer is requested to include the value of this parameter as the signature nonce
in the target signature.¶
alg
: The signer is requested to use the indicated signature algorithm from the HTTP Signature Algorithms Registry to create the target signature.¶
keyid
: The signer is requested to use the indicated key material to create the target signature.¶
tag
: The signer is requested to include the value of this parameter as the signature tag
in the target signature.¶
The receiver of an Accept-Signature field fulfills that header as follows:¶
-Parse the field value as a Dictionary¶
-For each member of the dictionary:¶
-The key is taken as the label of the output signature as specified in Section 4.1.¶
-Parse the value of the member to obtain the set of covered component identifiers.¶
-Determine that the covered components are applicable to the target message. If not, the process fails and returns an error.¶
-Process the requested parameters, such as the signing algorithm and key material. If any requested parameters cannot be fulfilled, or if the requested parameters conflict with those deemed appropriate to the target message, the process fails and returns an error.¶
-Select and generate any additional parameters necessary for completing the signature.¶
-Create the HTTP message signature over the target message.¶
-Create the Signature-Input and Signature values and associate them with the label.¶
-Optionally create any additional Signature-Input and Signature values, with unique labels not found in the Accept-Signature field.¶
-Combine all labeled Signature-Input and Signature values and attach both fields to the target message.¶
-By this process, a signature applied to a target message MUST have the same label, MUST include the same set of covered component, MUST process all requested parameters, and MAY have additional parameters.¶
-The receiver of an Accept-Signature field MAY ignore any signature request that does not fit application parameters.¶
-The target message MAY include additional signatures not specified by the Accept-Signature field. For example, to cover additional message components, the signer can create a second signature that includes the additional components as well as the signature output of the requested signature.¶
-IANA is asked to update one registry and create four new registries, according to the following sections.¶
-IANA is asked to update the -"Hypertext Transfer Protocol (HTTP) Field Name Registry" registry, -registering the following entries according to the table below:¶
-Field Name | -Status | -Reference | -
---|---|---|
Signature-Input | -permanent | -- Section 4.1 of RFC nnnn | -
Signature | -permanent | -- Section 4.2 of RFC nnnn | -
Accept-Signature | -permanent | -- Section 5.1 of RFC nnnn | -
This document defines HTTP Signature Algorithms, for which IANA is asked to create and maintain a new registry titled "HTTP Signature Algorithms". Initial values for this registry are given in Section 6.2.2. Future assignments and modifications to existing assignment are to be made through the Specification Required registration policy [RFC8126].¶
-The algorithms listed in this registry identify some possible cryptographic algorithms for applications to use with this specification, but the entries neither represent an exhaustive list of possible algorithms nor indicate fitness for purpose with any particular application of this specification. An application is free to implement any algorithm that suits its needs, provided the signer and verifier can agree to the parameters of that algorithm in a secure and deterministic fashion. When an application has a need to signal the use of a particular algorithm at runtime using the alg
signature parameter, this registry provides a mapping between the value of that parameter to a particular algorithm. However, use of the alg
parameter needs to be treated with caution to avoid various forms of algorithm confusion and substitution attacks, such as discussed in Section 7.3.6 and others.¶
The Status value should reflect standardization status and the broad opinion of relevant interest groups such as the IETF or security-related SDOs. When an algorithm is first registered, the Designated Expert (DE) should set the Status field to "Active" if there is consensus for the algorithm to be generally recommended as secure or "Provisional" if the algorithm has not reached that consensus, such as for an experimental algorithm. A status of "Provisional" does not mean that the algorithm is known to be insecure, but instead indicates that the algorithm has not reached consensus regarding its properties. If at a future time the algorithm as registered is found to have flaws, the registry entry can be updated and the algorithm can be marked as "Deprecated" to indicate that the algorithm has been found to have problems. This status does not preclude an application from using a particular algorithm, but serves to provide warning of possible known issues with an algorithm that need to be considered by the application. The DE can further ensure that the registration includes an explanation and reference for the Status value, which is particularly important for deprecated algorithms.¶
-The DE is expected to ensure that the algorithms referenced by a registered algorithm identifier are fully defined with all parameters (such as salt, hash, required key length, etc) fixed by the defining text. The DE is expected to ensure that the algorithm definition fully specifies the HTTP_SIGN
and HTTP_VERIFY
primitive functions, including how all defined inputs and outputs map to the underlying cryptographic algorithm. The DE is expected to reject any registrations that are aliases of existing registrations. The DE is expected to ensure all registrations follow the template presented in Section 6.2.1, including that the length of the name is not excessive while still being unique and recognizable.¶
This specification creates algorithm identifiers by including major parameters in the identifier string in order to make the algorithm name unique and recognizable by developers. However, algorithm identifiers in this registry are to be interpreted as whole string values and not as a combination of parts. That is to say, it is expected that implementors understand rsa-pss-sha512
as referring to one specific algorithm with its hash, mask, and salt values set as defined in the defining text that establishes this identifier. Implementors do not parse out the rsa
, pss
, and sha512
portions of the identifier to determine parameters of the signing algorithm from the string, and the registry of one combination of parameters does not imply the registration of other combinations.¶
An identifier for the HTTP Signature Algorithm. The name MUST be an ASCII string that conforms to the sf-string
ABNF rule in Section 3.3.3 of [STRUCTURED-FIELDS] and SHOULD NOT exceed 20 characters in length. The identifier MUST be unique within the context of the registry.¶
A brief description of the algorithm used to sign the signature base.¶
-The status of the algorithm. MUST start with one of the following values and MAY contain additional explanatory text. The options are: - - "Active": for algorithms without known problems. The signature algorithm is fully specified and its security properties are understood. - - "Provisional": for unproven algorithms. The signature algorithm is fully specified but its security properties are not known or proven. - - "Deprecated": for algorithms with know security issues. The signature algorithm is no longer recommended for general use and might be insecure or unsafe in some known circumstances.¶
-Reference to the document(s) that specify the - algorithm, preferably including a URI that can be used - to retrieve a copy of the document(s). An indication of the - relevant sections may also be included but is not required.¶
-Algorithm Name | -Description | -Status | -Specification document(s) | -
---|---|---|---|
- rsa-pss-sha512
- |
- RSASSA-PSS using SHA-512 | -Active | -- Section 3.3.1 of RFC nnnn | -
- rsa-v1_5-sha256
- |
- RSASSA-PKCS1-v1_5 using SHA-256 | -Active | -- Section 3.3.2 of RFC nnnn | -
- hmac-sha256
- |
- HMAC using SHA-256 | -Active | -- Section 3.3.3 of RFC nnnn | -
- ecdsa-p256-sha256
- |
- ECDSA using curve P-256 DSS and SHA-256 | -Active | -- Section 3.3.4 of RFC nnnn | -
- ecdsa-p384-sha384
- |
- ECDSA using curve P-384 DSS and SHA-384 | -Active | -- Section 3.3.5 of RFC nnnn | -
- ed25519
- |
- Edwards Curve DSA using curve edwards25519 | -Active | -- Section 3.3.6 of RFC nnnn | -
This document defines the signature parameters structure in Section 2.3, which may have parameters containing metadata about a message signature. IANA is asked to create and maintain a new registry titled "HTTP Signature Metadata Parameters" to record and maintain the set of parameters defined for use with member values in the signature parameters structure. Initial values for this registry are given in Section 6.3.2. Future assignments and modifications to existing assignments are to be made through the Expert Review registration policy [RFC8126].¶
-The DE is expected to ensure that the name follows the template presented in Section 6.3.1, including that the length of the name is not excessive while still being unique and recognizable for its defined function. The DE is expected to ensure that the defined functionality is clear and does not conflict with other registered parameters. The DE is expected to ensure that the definition of the metadata parameter includes its behavior when used as part of the normal signature process as well as when used in an Accept-Signature field.¶
-An identifier for the HTTP signature metadata parameter. The name MUST be an ASCII string that conforms to the key
ABNF rule defined in Section 3.1.2 of [STRUCTURED-FIELDS] and SHOULD NOT exceed 20 characters in length. The identifier MUST be unique within the context of the registry.¶
A brief description of the metadata parameter and what it represents.¶
-Reference to the document(s) that specify the - parameter, preferably including a URI that can be used - to retrieve a copy of the document(s). An indication of the - relevant sections may also be included but is not required.¶
-The table below contains the initial contents of the HTTP Signature Metadata Parameters Registry. Each row in the table represents a distinct entry in the registry.¶
-Name | -Description | -Specification document(s) | -
---|---|---|
- alg
- |
- Explicitly declared signature algorithm | -- Section 2.3 of RFC nnnn | -
- created
- |
- Timestamp of signature creation | -- Section 2.3 of RFC nnnn | -
- expires
- |
- Timestamp of proposed signature expiration | -- Section 2.3 of RFC nnnn | -
- keyid
- |
- Key identifier for the signing and verification keys used to create this signature | -- Section 2.3 of RFC nnnn | -
- nonce
- |
- A single-use nonce value | -- Section 2.3 of RFC nnnn | -
- tag
- |
- An application-specific tag for a signature | -- Section 2.3 of RFC nnnn | -
This document defines a method for canonicalizing HTTP message components, including components that can be derived from the context of the target message outside of the HTTP fields. These derived components are identified by a unique string, known as the component name. Component names for derived components always start with the "@" (at) symbol to distinguish them from HTTP field names. IANA is asked to create and maintain a new registry typed "HTTP Signature Derived Component Names" to record and maintain the set of non-field component names and the methods to produce their associated component values. Initial values for this registry are given in Section 6.4.2. Future assignments and modifications to existing assignments are to be made through the Expert Review registration policy [RFC8126].¶
-The DE is expected to ensure that the name follows the template presented in Section 6.4.1, including that the length of the name is not excessive while still being unique and recognizable for its defined function. The DE is expected to ensure that the component value represented by the registration request can be deterministically derived from the target HTTP message. The DE is expected to ensure that any parameters defined for the registration request are clearly documented, along with their effects on the component value. The DE should also ensure that the registration request is not sufficiently distinct from existing derived component definitions to warrant its registration. When setting a registered item's status to "Deprecated", the DE should ensure that a reason for the deprecation is documented, along with instructions for moving away from the deprecated functionality.¶
-A name for the HTTP derived component. The name MUST begin with the "@"
character followed by an ASCII string consisting only of lower-case characters ("a"
- "z"
), digits ("0"
- "9"
), and hyphens ("-"
), and SHOULD NOT exceed 20 characters in length. The name MUST be unique within the context of the registry.¶
A description of the derived component.¶
-A brief text description of the status of the algorithm. The description MUST begin with one of "Active" or "Deprecated", and MAY provide further context or explanation as to the reason for the status. A value of "Deprecated" indicates that the derived component name is no longer recommended for use.¶
-The valid message targets for the derived parameter. MUST be one of the values "Request", "Response", or "Request, Response". The semantics of these are defined in Section 2.2.¶
-Reference to the document(s) that specify the - derived component, preferably including a URI that can be used - to retrieve a copy of the document(s). An indication of the - relevant sections may also be included but is not required.¶
-The table below contains the initial contents of the HTTP Signature Derived Component Names Registry.¶
-Name | -Description | -Status | -Target | -Specification document(s) | -
---|---|---|---|---|
- @signature-params
- |
- Reserved for signature parameters line in signature base | -Active | -Request, Response | -- Section 2.3 of RFC nnnn | -
- @method
- |
- The HTTP request method | -Active | -Request | -- Section 2.2.1 of RFC nnnn | -
- @authority
- |
- The HTTP authority, or target host | -Active | -Request | -- Section 2.2.3 of RFC nnnn | -
- @scheme
- |
- The URI scheme of the request URI | -Active | -Request | -- Section 2.2.4 of RFC nnnn | -
- @target-uri
- |
- The full target URI of the request | -Active | -Request | -- Section 2.2.2 of RFC nnnn | -
- @request-target
- |
- The request target of the request | -Active | -Request | -- Section 2.2.5 of RFC nnnn | -
- @path
- |
- The full path of the request URI | -Active | -Request | -- Section 2.2.6 of RFC nnnn | -
- @query
- |
- The full query of the request URI | -Active | -Request | -- Section 2.2.7 of RFC nnnn | -
- @query-param
- |
- A single named query parameter | -Active | -Request | -- Section 2.2.8 of RFC nnnn | -
- @status
- |
- The status code of the response | -Active | -Response | -- Section 2.2.9 of RFC nnnn | -
This document defines several kinds of component identifiers, some of which can be parameterized in specific circumstances to provide unique modified behavior. IANA is asked to create and maintain a new registry typed "HTTP Signature Component Parameters" to record and maintain the set of parameters names, the component identifiers they are associated with, and the modifications these parameters make to the component value. Definitions of parameters MUST define the targets to which they apply (such as specific field types, derived components, or contexts). Initial values for this registry are given in Section 6.5.2. Future assignments and modifications to existing assignments are to be made through the Expert Review registration policy [RFC8126].¶
-The DE is expected to ensure that the name follows the template presented in Section 6.5.1, including that the length of the name is not excessive while still being unique and recognizable for its defined function. The DE is expected to ensure that the definition of the field sufficiently defines any interactions incompatibilities with other existing parameters known at the time of the registration request. If the parameter changes the component value, the DE is expected to ensure that the component value defined by the component identifier with the parameter applied can be deterministically derived from the target HTTP message.¶
-A name for the parameter. The name MUST be an ASCII string that conforms to the key
ABNF rule defined in Section 3.1.2 of [STRUCTURED-FIELDS] and SHOULD NOT exceed 20 characters in length. The name MUST be unique within the context of the registry.¶
A description of the parameter's function.¶
-Reference to the document(s) that specify the - derived component, preferably including a URI that can be used - to retrieve a copy of the document(s). An indication of the - relevant sections may also be included but is not required.¶
-The table below contains the initial contents of the HTTP Signature Derived Component Names Registry.¶
-Name | -Description | -Specification document(s) | -
---|---|---|
- sf
- |
- Strict structured field serialization | -- Section 2.1.1 of RFC nnnn | -
- key
- |
- Single key value of dictionary structured fields | -- Section 2.1.2 of RFC nnnn | -
- bs
- |
- Byte Sequence wrapping indicator | -- Section 2.1.3 of RFC nnnn | -
- tr
- |
- Trailer | -- Section 2.1.4 of RFC nnnn | -
- req
- |
- Related request indicator | -- Section 2.2.4 of RFC nnnn | -
- name
- |
- Single named query parameter | -- Section 2.2.8 of RFC nnnn | -
In order for an HTTP message to be considered covered by a signature, all of the following conditions have to be true:¶
-a signature is expected or allowed on the message by the verifier¶
-the signature exists on the message¶
-the signature is verified against the identified key material and algorithm¶
-the key material and algorithm are appropriate for the context of the message¶
-the signature is within expected time boundaries¶
-the signature covers the expected content, including any critical components¶
-the list of covered components is applicable to the context of the message¶
-In addition to the application requirement definitions listed in Section 1.4, the following security considerations provide discussion and context to the requirements of creating and verifying signatures on HTTP messages.¶
-HTTP Message Signatures only provide security if the signature is verified by the verifier. Since the message to which the signature is attached remains a valid HTTP message without the signature fields, it is possible for a verifier to ignore the output of the verification function and still process the message. Common reasons for this could be relaxed requirements in a development environment or a temporary suspension of enforcing verification during debugging an overall system. Such temporary suspensions are difficult to detect under positive-example testing since a good signature will always trigger a valid response whether or not it has been checked.¶
-To detect this, verifiers should be tested using both valid and invalid signatures, ensuring that the invalid signature fails as expected.¶
-The use of HTTP Message Signatures does not negate the need for TLS or its equivalent to protect information in transit. Message signatures provide message integrity over the covered message components but do not provide any confidentiality for the communication between parties.¶
-TLS provides such confidentiality between the TLS endpoints. As part of this, TLS also protects the signature data itself from being captured by an attacker, which is an important step in preventing signature replay (Section 7.2.2).¶
-When TLS is used, it needs to be deployed according to the recommendations in [BCP195].¶
-Any portions of the message not covered by the signature are susceptible to modification by an attacker without affecting the signature. An attacker can take advantage of this by introducing or modifying a header field or other message component that will change the processing of the message but will not be covered by the signature. Such an altered message would still pass signature verification, but when the verifier processes the message as a whole, the unsigned content injected by the attacker would subvert the trust conveyed by the valid signature and change the outcome of processing the message.¶
-To combat this, an application of this specification should require as much of the message as possible to be signed, within the limits of the application and deployment. The verifier should only trust message components that have been signed. Verifiers could also strip out any sensitive unsigned portions of the message before processing of the message continues.¶
-Since HTTP Message Signatures allows sub-portions of the HTTP message to be signed, it is possible for two different HTTP messages to validate against the same signature. The most extreme form of this would be a signature over no message components. If such a signature were intercepted, it could be replayed at will by an attacker, attached to any HTTP message. Even with sufficient component coverage, a given signature could be applied to two similar HTTP messages, allowing a message to be replayed by an attacker with the signature intact.¶
-To counteract these kinds of attacks, it's first important for the signer to cover sufficient portions of the message to differentiate it from other messages. In addition, the signature can use the nonce
signature parameter to provide a per-message unique value to allow the verifier to detect replay of the signature itself if a nonce value is repeated. Furthermore, the signer can provide a timestamp for when the signature was created and a time at which the signer considers the signature to be expired, limiting the utility of a captured signature value.¶
If a verifier wants to trigger a new signature from a signer, it can send the Accept-Signature
header field with a new nonce
parameter. An attacker that is simply replaying a signature would not be able to generate a new signature with the chosen nonce value.¶
Applications of HTTP Message Signatures need to decide which message components will be covered by the signature. Depending on the application, some components could be expected to be changed by intermediaries prior to the signature's verification. If these components are covered, such changes would, by design, break the signature.¶
-However, the HTTP Message Signature standard allows for flexibility in determining which components are signed precisely so that a given application can choose the appropriate portions of the message that need to be signed, avoiding problematic components. For example, a web application framework that relies on rewriting query parameters might avoid use of the @query
derived component in favor of sub-indexing the query value using @query-param
derived components instead.¶
Some components are expected to be changed by intermediaries and ought not to be signed under most circumstance. The Via
and Forwarded
header fields, for example, are expected to be manipulated by proxies and other middle-boxes, including replacing or entirely dropping existing values. These fields should not be covered by the signature except in very limited and tightly-coupled scenarios.¶
Additional considerations for choosing signature aspects are discussed in Section 1.4.¶
-Some HTTP fields have values and interpretations that are similar to HTTP signature parameters or derived components. In most cases, it is more desirable to sign the non-field alternative. In particular, the following fields should usually not be included in the signature unless the application specifically requires it:¶
-The "date" field value represents the timestamp of the HTTP message. However, the creation time of the signature itself is encoded in the created
signature parameter. These two values can be different, depending on how the signature and the HTTP message are created and serialized. Applications processing signatures for valid time windows should use the created
signature parameter for such calculations. An application could also put limits on how much skew there is between the "date" field and the created
signature parameter, in order to limit the application of a generated signature to different HTTP messages. See also Section 7.2.2 and Section 7.2.1.¶
The "host" header field is specific to HTTP/1.1, and its functionality is subsumed by the "@authority" derived component, defined in Section 2.2.3. In order to preserve the value across different HTTP versions, applications should always use the "@authority" derived component. See also Section 7.5.4.¶
-HTTP Message Signature values are identified in the Signature and Signature-Input field values by unique labels. These labels are chosen only when attaching the signature values to the message and are not accounted for in the signing process. An intermediary is allowed to re-label an existing signature when processing the message.¶
-Therefore, applications should not rely on specific labels being present, and applications should not put semantic meaning on the labels themselves. Instead, additional signature parameters can be used to convey whatever additional meaning is required to be attached to and covered by the signature. In particular, the tag
parameter can be used to define an application-specific value as described in Section 7.2.7.¶
Since multiple signatures can be applied to one message (Section 4.3), it is possible for an attacker to attach their own signature to a captured message without modifying existing signatures. This new signature could be completely valid based on the attacker's key, or it could be an invalid signature for any number of reasons. Each of these situations need to be accounted for.¶
-A verifier processing a set of valid signatures needs to account for all of the signers, identified by the signing keys. Only signatures from expected signers should be accepted, regardless of the cryptographic validity of the signature itself.¶
-A verifier processing a set of signatures on a message also needs to determine what to do when one or more of the signatures are not valid. If a message is accepted when at least one signature is valid, then a verifier could drop all invalid signatures from the request before processing the message further. Alternatively, if the verifier rejects a message for a single invalid signature, an attacker could use this to deny service to otherwise valid messages by injecting invalid signatures alongside the valid ones.¶
-Multiple applications and protocols could apply HTTP signatures on the same message simultaneously. In fact, this is a desired feature in many circumstances as described in Section 4.3. A naive verifier could become confused in processing multiple signatures, either accepting or rejecting a message based on an unrelated or irrelevant signature. In order to help an application select which signatures apply to its own processing, the application can declare a specific value for the tag
signature parameter as defined in Section 2.3. For example, a signature targeting an application gateway could require tag="app-gateway"
as part of the signature parameters for that application.¶
The use of the tag
parameter does not prevent an attacker from also using the same value as a target application, since the parameter's value is public and otherwise unrestricted. As a consequence, a verifier should only use value of the tag
parameter to limit which signatures to check. Each signature still needs to be examined by the verifier to ensure that sufficient coverage is provided, as discussed in Section 7.2.1.¶
On its own, this specification does not provide coverage for the content of an HTTP message under the signature, either in request or response. However, [DIGEST] defines a set of fields that allow a cryptographic digest of the content to be represented in a field. Once this field is created, it can be included just like any other field as defined in Section 2.1.¶
-For example, in the following response message:¶
- -The digest of the content can be added to the Content-Digest field as follows:¶
- -This field can be included in a signature base just like any other field along with the basic signature parameters:¶
--"@status": 200 -"content-digest": \ - sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=: -"@signature-input": ("@status" "content-digest") -¶ -
From here, the signing process proceeds as usual.¶
-Upon verification, it is important that the verifier validate not only the signature but also the value of the Content-Digest field itself against the actual received content. Unless the verifier performs this step, it would be possible for an attacker to substitute the message content but leave the Content-Digest field value untouched to pass the signature. Since only the field value is covered by the signature directly, checking only the signature is not sufficient protection against such a substitution attack.¶
-As discussed in [DIGEST], the value of the Content-Digest field is dependent on the content encoding of the message. If an intermediary changes the content encoding, the resulting Content-Digest value would change, which would in turn invalidate the signature. Any intermediary performing such an action would need to apply a new signature with the updated Content-Digest field value, similar to the reverse proxy use case discussed in Section 4.3.¶
-Applications that make use of the request-response parameter (Section 2.4) also need to be aware of the limitations in this functionality. Specifically, if a client does not include something like a Content-Digest header field in the request, the server is unable to include a signature that covers the request's content.¶
-The HTTP Message Signatures specification does not define any of its own cryptographic primitives, and instead relies on other specifications to define such elements. If the signature algorithm or key used to process the signature base is vulnerable to any attacks, the resulting signature will also be susceptible to these same attacks.¶
-A common attack against signature systems is to force a signature collision, where the same signature value successfully verifies against multiple different inputs. Since this specification relies on reconstruction of the signature base from an HTTP message, and the list of components signed is fixed in the signature, it is difficult but not impossible for an attacker to effect such a collision. An attacker would need to manipulate the HTTP message and its covered message components in order to make the collision effective.¶
-To counter this, only vetted keys and signature algorithms should be used to sign HTTP messages. The HTTP Message Signatures Algorithm Registry is one source of trusted signature algorithms for applications to apply to their messages.¶
-While it is possible for an attacker to substitute the signature parameters value or the signature value separately, the signature base generation algorithm (Section 2.5) always covers the signature parameters as the final value in the signature base using a deterministic serialization method. This step strongly binds the signature base with the signature value in a way that makes it much more difficult for an attacker to perform a partial substitution on the signature bases.¶
-A foundational assumption of signature-based cryptographic systems is that the signing key is not compromised by an attacker. If the keys used to sign the message are exfiltrated or stolen, the attacker will be able to generate their own signatures using those keys. As a consequence, signers have to protect any signing key material from exfiltration, capture, and use by an attacker.¶
-To combat this, signers can rotate keys over time to limit the amount of time stolen keys are useful. Signers can also use key escrow and storage systems to limit the attack surface against keys. Furthermore, the use of asymmetric signing algorithms exposes key material less than the use of symmetric signing algorithms (Section 7.3.3).¶
-The HTTP Message Signatures specification allows for both asymmetric and symmetric cryptography to be applied to HTTP messages. By its nature, symmetric cryptographic methods require the same key material to be known by both the signer and verifier. This effectively means that a verifier is capable of generating a valid signature, since they have access to the same key material. An attacker that is able to compromise a verifier would be able to then impersonate a signer.¶
-Where possible, asymmetric methods or secure key agreement mechanisms should be used in order to avoid this type of attack. When symmetric methods are used, distribution of the key material needs to be protected by the overall system. One technique for this is the use of separate cryptographic modules that separate the verification process (and therefore the key material) from other code, minimizing the vulnerable attack surface. Another technique is the use of key derivation functions that allow the signer and verifier to agree on unique keys for each message without having to share the key values directly.¶
-Additionally, if symmetric algorithms are allowed within a system, special care must be taken to avoid key downgrade attacks (Section 7.3.6).¶
-The existence of a valid signature on an HTTP message is not sufficient to prove that the message has been signed by the appropriate party. It is up to the verifier to ensure that a given key and algorithm are appropriate for the message in question. If the verifier does not perform such a step, an attacker could substitute their own signature using their own key on a message and force a verifier to accept and process it. To combat this, the verifier needs to ensure that not only does the signature validate for a message, but that the key and algorithm used are appropriate.¶
-Some cryptographic primitives such as RSA PSS and ECDSA have non-deterministic outputs, which include some amount of entropy within the algorithm. For such algorithms, multiple signatures generated in succession will not match. A lazy implementation of a verifier could ignore this distinction and simply check for the same value being created by re-signing the signature base. Such an implementation would work for deterministic algorithms such as HMAC and EdDSA but fail to verify valid signatures made using non-deterministic algorithms. It is therefore important that a verifier always use the correctly-defined verification function for the algorithm in question and not do a simple comparison.¶
-Applications of this specification need to protect against key specification downgrade attacks. For example, the same RSA key can be used for both RSA-PSS and RSA v1.5 signatures. If an application expects a key to only be used with RSA-PSS, it needs to reject signatures for that key using the weaker RSA 1.5 specification.¶
-Another example of a downgrade attack occurs when an asymmetric algorithm is expected, such as RSA-PSS, but an attacker substitutes a signature using symmetric algorithm, such as HMAC. A naive verifier implementation could use the value of the public RSA key as the input to the HMAC verification function. Since the public key is known to the attacker, this would allow the attacker to create a valid HMAC signature against this known key. To prevent this, the verifier needs to ensure that both the key material and the algorithm are appropriate for the usage in question. Additionally, while this specification does allow runtime specification of the algorithm using the alg
signature parameter, applications are encouraged to use other mechanisms such as static configuration or higher protocol-level algorithm specification instead, preventing an attacker from substituting the algorithm specified.¶
When applying the request-response parameter (Section 2.4) or multiple signatures (Section 4.3) to a message, it is possible to sign the value of an existing Signature field, thereby covering the bytes of the existing signature output in the new signature's value. While it would seem that this practice would transitively cover the components under the original signature in a verifiable fashion, the attacks described in [JACKSON2019] can be used to impersonate a signature output value on an unrelated message.¶
-In this example, Alice intends to send a signed request to Bob, and Bob wants to provide a signed response to Alice that includes a cryptographic proof that Bob is responding to Alice's incoming message. Mallory wants to intercept this traffic and replace Alice's message with her own, without Alice being aware that the interception has taken place.¶
-Alice creates a message, Req_A
and applies a signature Sig_A
using her private key Key_A_Sign
.¶
Alice believes she is sending Req_A
to Bob.¶
Mallory intercepts Req_A
and reads the value Sig_A
from this message.¶
Mallory generates a different message Req_M
to send to Bob instead.¶
Mallory crafts a signing key Key_M_Sign
such that she can create a valid signature Sig_M
over her request Req_M
using this key, but the byte value of Sig_M
exactly equals that of Sig_A
.¶
Mallory sends Req_M
with Sig_M
to Bob.¶
Bob validates Sig_M
against Mallory's verification key, Key_M_Verify
. At no time does Bob think that he's responding to Alice.¶
Bob responds with response message Res_B
to Req_M
and creates signature Sig_B
over this message using his key, Key_B_Sign
. Bob includes the value of Sig_M
under Sig_B
's covered components, but nothing elese from the request message.¶
Mallory receives the response Res_B
from Bob, including the signature Sig_B
value. Mallory replays this response to Alice.¶
Alice reads Res_B
from Mallory and verifies Sig_B
using Bob's verification key, Key_B_Verify
. Alice includes the bytes of her original signature Sig_A
in the signature base, and the signature verifies.¶
Alice is led to believe that Bob has responded to her message, and believes she has cryptographic proof of this happening, but in fact Bob responded to Mallory's malicious request and Alice is none the wiser.¶
-To mitigate this, Bob can sign more portions of the request message than just the Signature field, in order to more fully differentiate Alice's message from Mallory's. Applications using this feature, particularly for non-repudiation purposes, can stipulate that any components required in the original signature also be covered separately in the second signature. For signed messages, requiring coverage of the corresponding Signature-Input field of the first signature ensures that unique items such as nonces and timestamps are also covered sufficiently by the second signature.¶
-An attacker could effectively deny a service by modifying an otherwise benign signature parameter or signed message component. While rejecting a modified message is the desired behavior, consistently failing signatures could lead to the verifier turning off signature checking in order to make systems work again (see Section 7.1.1), or to the application minimizing the signed component requirements.¶
-If such failures are common within an application, the signer and verifier should compare their generated signature bases with each other to determine which part of the message is being modified. If an expected modification is found, the signer and verifier can agree on an alternative set of requirements that will pass. However, the signer and verifier should not remove the requirement to sign the modified component when it is suspected an attacker is modifying the component.¶
-The verifier needs to make sure that the signed message components match those in the message itself. For example, the @method
derived component requires that the value within the signature base be the same as the HTTP method used when presenting this message. This specification encourages this by requiring the verifier to derive the signature base from the message, but lazy caching or conveyance of a raw signature base to a processing subsystem could lead to downstream verifiers accepting a message that does not match the presented signature.¶
To counter this, the component that generates the signature base needs to be trusted by both the signer and verifier within a system.¶
-The signature context for deriving message component values includes the target HTTP Message itself, any associated messages (such as the request that triggered a response), and additional information that the signer or verifier has access to. Both signers and verifiers need to carefully consider the source of all information when creating component values for the signature base and take care not to take information from untrusted sources. Otherwise, an attacker could leverage such a loosely-defined message context to inject their own values into the signature base string, overriding or corrupting the intended values.¶
-For example, in most situations, the target URI of the message is defined in [HTTP], Section 7.1. However, let's say that there is an application that requires signing of the @authority
of the incoming request, but the application doing the processing is behind a reverse proxy. Such an application would expect a change in the @authority
value, and it could be configured to know the external target URI as seen by the client on the other side of the proxy. This application would use this configured value as its target URI for the purposes of deriving message component values such as @authority
instead of using the target URI of the incoming message.¶
This approach is not without problems, as a misconfigured system could accept signed requests intended for different components in the system. For this scenario, an intermediary could instead add its own signature to be verified by the application directly, as demonstrated in Section 4.3. This alternative approach requires a more active intermediary but relies less on the target application knowing external configuration values.¶
-For another example, Section 2.4 defines a method for signing response messages but including portions of the request message that triggered the response. In this case, the context for component value calculation is the combination of the response and request message, not just the single message to which the signature is applied. For this feature, the req
flag allows both signer to explicitly signal which part of the context is being sourced for a component identifier's value. Implementations need to ensure that only the intended message is being referred to for each component, otherwise an attacker could attempt to subvert a signature by manipulating one side or the other.¶
It is possible that the context for deriving message component values could be distinct for each signature present within a single message. This is particularly the case when proxies mutate messages and include signatures over the mutated values, in addition to any existing signatures. For example, a reverse proxy can replace a public hostname in a request to a service with the hostname for the individual service host that it is forwarding the request on to. If both the client and the reverse proxy add signatures covering @authority
, the service host will see two signatures on the request, each signing different values for the @authority
message component, reflecting the change to that component as the message made its way from the client to the service host.¶
In such a case, it's common for the internal service to verify only one of the signatures or to use externally-configured information, as discussed in Section 7.4.3. However, a verifier processing both signatures has to use a different message component context for each signature, since the component value for the @authority
component will be different for each signature. Verifiers like this need to be aware of both the reverse proxy's context for incoming messages as well as the target service's context for the message coming from the reverse proxy. The verifier needs to take particular care to apply the correct context to the correct signature, otherwise an attacker could use knowledge of this complex setup to confuse the inputs to the verifier.¶
Such verifiers also need to ensure that any differences in message component contexts between signatures are expected and permitted. For example, in the above scenario, the reverse proxy could include the original hostname in a Forwarded
header field, and sign @authority
, forwarded
, and the client's entry in the signature
field. The verifier can use the hostname from the Forwarded
header field to confirm that the hostname was transformed as expected.¶
The definition of HTTP field names does not allow for the use of the @
character anywhere in the name. As such, since all derived component names start with the @
character, these namespaces should be completely separate. However, some HTTP implementations are not sufficiently strict about the characters accepted in HTTP field names. In such implementations, a sender (or attacker) could inject a header field starting with an @
character and have it passed through to the application code. These invalid header fields could be used to override a portion of the derived message content and substitute an arbitrary value, providing a potential place for an attacker to mount a signature collision (Section 7.3.1) attack or other functional substitution attack (such as using the signature from a GET request on a crafted POST request).¶
To combat this, when selecting values for a message component, if the component name starts with the @
character, it needs to be processed as a derived component and never taken as a fields. Only if the component name does not start with the @
character can it be taken from the fields of the message. The algorithm discussed in Section 2.5 provides a safe order of operations.¶
The signature base generation algorithm (Section 2.5) uses the value of an HTTP field as its component value. In the common case, this amounts to taking the actual bytes of the field value as the component value for both the signer and verifier. However, some field values allow for transformation of the values in semantically equivalent ways that alter the bytes used in the value itself. For example, a field definition can declare some or all of its value to be case-insensitive, or to have special handling of internal whitespace characters. Other fields have expected transformations from intermediaries, such as the removal of comments in the Via
header field. In such cases, a verifier could be tripped up by using the equivalent transformed field value, which would differ from the byte value used by the signer. The verifier would have a difficult time finding this class of errors since the value of the field is still acceptable for the application, but the actual bytes required by the signature base would not match.¶
When processing such fields, the signer and verifier have to agree how to handle such transformations, if at all. One option is to not sign problematic fields, but care must be taken to ensure that there is still sufficient signature coverage (Section 7.2.1) for the application. Another option is to define an application-specific canonicalization value for the field before it is added to the HTTP message, such as to always remove internal comments before signing, or to always transform values to lowercase. Since these transformations are applied prior to the field being used as input to the signature base generation algorithm, the signature base will still simply contain the byte value of the field as it appears within the message. If the transformations were to be applied after the value is extracted from the message but before it is added to the signature base, different attack surfaces such as value substitution attacks could be launched against the application. All application-specific additional rules are outside the scope of this specification, and by their very nature these transformations would harm interoperability of the implementation outside of this specific application. It is recommended that applications avoid the use of such additional rules wherever possible.¶
-Several parts of this specification rely on the parsing of structured field values [STRUCTURED-FIELDS]. In particular, normalization of HTTP structured field values (Section 2.1.1), referencing members of a dictionary structured field (Section 2.1.2), and processing the @signature-input
value when verifying a signature (Section 3.2). While structured field values are designed to be relatively simple to parse, a naive or broken implementation of such a parser could lead to subtle attack surfaces being exposed in the implementation.¶
For example, if a buggy parser of the @signature-input
value does not enforce proper closing of quotes around string values within the list of component identifiers, an attacker could take advantage of this and inject additional content into the signature base through manipulating the Signature-Input field value on a message.¶
To counteract this, implementations should use fully compliant and trusted parsers for all structured field processing, both on the signer and verifier side.¶
-Some message components are expressed in different ways across HTTP versions. For example, the authority of the request target is sent using the Host
header field in HTTP/1.1 but with the :authority
pseudo-header in HTTP/2. If a signer sends an HTTP/1.1 message and signs the Host
field, but the message is translated to HTTP/2 before it reaches the verifier, the signature will not validate as the Host
header field could be dropped.¶
It is for this reason that HTTP Message Signatures defines a set of derived components that define a single way to get value in question, such as the @authority
derived component (Section 2.2.3) in lieu of the Host
header field. Applications should therefore prefer derived components for such options where possible.¶
Any ambiguity in the generation of the signature base could provide an attacker with leverage to substitute or break a signature on a message. Some message component values, particularly HTTP field values, are potentially susceptible to broken implementations that could lead to unexpected and insecure behavior. Naive implementations of this specification might implement HTTP field processing by taking the single value of a field and using it as the direct component value without processing it appropriately.¶
-For example, if the handling of obs-fold
field values does not remove the internal line folding and whitespace, additional newlines could be introduced into the signature base by the signer, providing a potential place for an attacker to mount a signature collision (Section 7.3.1) attack. Alternatively, if header fields that appear multiple times are not joined into a single string value, as is required by this specification, similar attacks can be mounted as a signed component value would show up in the signature base more than once and could be substituted or otherwise attacked in this way.¶
To counter this, the entire field value processing algorithm needs to be implemented by all implementations of signers and verifiers.¶
-When an HTTP field occurs multiple times in a single message, these values need to be combined into a single one-line string value to be included in the HTTP signature base, as described in Section 2.5. Not all HTTP fields can be combined into a single value in this way and still be a valid value for the field. For the purposes of generating the signature base, the message component value is never meant to be read back out of the signature base string or used in the application. Therefore it is considered best practice to treat the signature base generation algorithm separately from processing the field values by the application, particularly for fields that are known to have this property. If the field values that are being signed do not validate, the signed message should also be rejected.¶
-If an HTTP field allows for unquoted commas within its values, combining multiple field values can lead to a situation where two semantically different messages produce the same line in a signature base. For example, take the following hypothetical header field with an internal comma in its syntax, here used to define two separate lists of values:¶
- -For this header field, sending all of these values as a single field value results in a single list of values:¶
- -Both of these messages would create the following line in the signature base:¶
--"example-header": value, with, lots, of, commas -¶ -
Since two semantically distinct inputs can create the same output in the signature base, special care has to be taken when handling such values.¶
-Specifically, the Set-Cookie field [COOKIE] defines an internal syntax that does not conform to the List syntax in [STRUCTURED-FIELDS]. In particular some portions allow unquoted commas, and the field is typically sent as multiple separate field lines with distinct values when sending multiple cookies. When multiple Set-Cookie fields are sent in the same message, it is not generally possible to combine these into a single line and be able to parse and use the results, as discussed in [HTTP], Section 5.3. Therefore, all the cookies need to be processed from their separate header values, without being combined, while the signature base needs to be processed from the special combined value generated solely for this purpose. If the cookie value is invalid, the signed message ought to be rejected as this is a possible padding attack as described in Section 7.5.7.¶
-To deal with this, an application can choose to limit signing of problematic fields like Set-Cookie, such as including the field in a signature only when a single field value is present and the results would be unambiguous. Similar caution needs to be taken with all fields that could have non-deterministic mappings into the signature base. Signers can also make use of the bs
parameter to armor such fields, as described in Section 2.1.3.¶
Since HTTP field values need to be combined in a single string value to be included in the HTTP signature base, as described in Section 2.5, it is possible for an attacker to inject an additional value for a given field and add this to the signature base of the verifier.¶
-In most circumstances, this causes the signature validation to fail as expected, since the new signature base value will not match the one used by the signer to create the signature. However, it is theoretically possible for the attacker to inject both a garbage value to a field and a desired value to another field in order to force a particular input. This is a variation of the collision attack described in Section 7.3.1, where the attacker accomplishes their change in the message by adding to existing field values.¶
-To counter this, an application needs to validate the content of the fields covered in the signature in addition to ensuring that the signature itself validates. With such protections, the attacker's padding attack would be rejected by the field value processor, even in the case where the attacker could force a signature collision.¶
-The HTML form parameters format defined in the "application/x-www-form-urlencoded" section of [HTMLURL], is widely deployed and supported by many application frameworks. For convenience, some of these frameworks in particular combine query parameters that are found in the HTTP query and those found in the message content, particularly for POST message with a Content-Type value of "application/x-www-form-urlencoded". The @query-param
derived component identifier defined in Section 2.2.8 draws its values only from the query section of the target URI of the request. As such, it would be possible for an attacker to shadow or replace query parameters in a request by overriding the signed query parameter with an unsigned form parameter, or vice versa.¶
To counter this, an application needs to make sure that values used for the signature base and the application are drawn from a consistent context, in this case the query component of the target URI. Additionally, when the HTTP request has content, an application should sign the message content as well, as discussed in Section 7.2.8.¶
-If a signer uses the same key with multiple verifiers, or uses the same key over time with a single verifier, the ongoing use of that key can be used to track the signer throughout the set of verifiers that messages are sent to. Since cryptographic keys are meant to be functionally unique, the use of the same key over time is a strong indicator that it is the same party signing multiple messages.¶
-In many applications, this is a desirable trait, and it allows HTTP Message Signatures to be used as part of authenticating the signer to the verifier. However, it could be unintentional tracking that a signer might not be aware of. To counter this kind of tracking, a signer can use a different key for each verifier that it is in communication with. Sometimes, a signer could also rotate their key when sending messages to a given verifier. These approaches do not negate the need for other anti-tracking techniques to be applied as necessary.¶
-HTTP Message Signatures do not provide confidentiality of any of the information protected by the signature. The content of the HTTP message, including the value of all fields and the value of the signature itself, is presented in plaintext to any party with access to the message.¶
-To provide confidentiality at the transport level, TLS or its equivalent can be used as discussed in Section 7.1.2.¶
-It is important to balance the need for providing useful feedback to developers on error conditions without providing additional information to an attacker. For example, a naive but helpful server implementation might try to indicate the required key identifier needed for requesting a resource. If someone knows who controls that key, a correlation can be made between the resource's existence and the party identified by the key. Access to such information could be used by an attacker as a means to target the legitimate owner of the resource for further attacks.¶
-A core design tenet of this specification is that all message components covered by the signature need to be available to the verifier in order to recreate the signature base and verify the signature. As a consequence, if an application of this specification requires that a particular field be signed, the verifier will need access to the value of that field.¶
-For example, in some complex systems with intermediary processors this could cause the surprising behavior of an intermediary not being able to remove privacy-sensitive information from a message before forwarding it on for processing, for fear of breaking the signature. A possible mitigation for this specific situation would be for the intermediary to verify the signature itself, and then modify the message to remove the privacy-sensitive information. The intermediary can add its own signature at this point to signal to the next destination that the incoming signature was validated, as is shown in the example in Section 4.3.¶
-There have been many attempts to create signed HTTP messages in the past, including other non-standardized definitions of the Signature field, which is used within this specification. It is recommended that developers wishing to support both this specification and other historical drafts do so carefully and deliberately, as incompatibilities between this specification and various versions of other drafts could lead to unexpected problems.¶
-It is recommended that implementers first detect and validate the Signature-Input field defined in this specification to detect that this standard is in use and not an alternative. If the Signature-Input field is present, all Signature fields can be parsed and interpreted in the context of this specification.¶
-The following non-normative examples are provided as a means of testing implementations of HTTP Message Signatures. The signed messages given can be used to create the signature base with the stated parameters, creating signatures using the stated algorithms and keys.¶
-The private keys given can be used to generate signatures, though since several of the demonstrated algorithms are nondeterministic, the results of a signature are expected to be different from the exact bytes of the examples. The public keys given can be used to validate all signed examples.¶
-This section provides cryptographic keys that are referenced in example signatures throughout this document. These keys MUST NOT be used for any purpose other than testing.¶
-The key identifiers for each key are used throughout the examples in this specification. It is assumed for these examples that the signer and verifier can unambiguously dereference all key identifiers used here, and that the keys and algorithms used are appropriate for the context in which the signature is presented.¶
-The components for each private key in PEM format can be displayed by executing the following OpenSSL command:¶
--openssl pkey -text -¶ -
This command was tested with all the example keys on OpenSSL version 1.1.1m. Note that some systems cannot produce or use all of these keys directly, and may require additional processing. All keys are also made available in JWK format.¶
-The following key is a 2048-bit RSA public and private key pair, referred to in this document
-as test-key-rsa
. This key is encoded in PEM Format, with no encryption.¶
------BEGIN RSA PUBLIC KEY----- -MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw -WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq -MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg -kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P -uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ -PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB ------END RSA PUBLIC KEY----- - ------BEGIN RSA PRIVATE KEY----- -MIIEqAIBAAKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsP -BRrwWEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsd -JKFqMGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75 -jfZgkne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKI -lE0PuKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZ -SFlQPSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQABAoIBAG/JZuSWdoVHbi56 -vjgCgkjg3lkO1KrO3nrdm6nrgA9P9qaPjxuKoWaKO1cBQlE1pSWp/cKncYgD5WxE -CpAnRUXG2pG4zdkzCYzAh1i+c34L6oZoHsirK6oNcEnHveydfzJL5934egm6p8DW -+m1RQ70yUt4uRc0YSor+q1LGJvGQHReF0WmJBZHrhz5e63Pq7lE0gIwuBqL8SMaA -yRXtK+JGxZpImTq+NHvEWWCu09SCq0r838ceQI55SvzmTkwqtC+8AT2zFviMZkKR -Qo6SPsrqItxZWRty2izawTF0Bf5S2VAx7O+6t3wBsQ1sLptoSgX3QblELY5asI0J -YFz7LJECgYkAsqeUJmqXE3LP8tYoIjMIAKiTm9o6psPlc8CrLI9CH0UbuaA2JCOM -cCNq8SyYbTqgnWlB9ZfcAm/cFpA8tYci9m5vYK8HNxQr+8FS3Qo8N9RJ8d0U5Csw -DzMYfRghAfUGwmlWj5hp1pQzAuhwbOXFtxKHVsMPhz1IBtF9Y8jvgqgYHLbmyiu1 -mwJ5AL0pYF0G7x81prlARURwHo0Yf52kEw1dxpx+JXER7hQRWQki5/NsUEtv+8RT -qn2m6qte5DXLyn83b1qRscSdnCCwKtKWUug5q2ZbwVOCJCtmRwmnP131lWRYfj67 -B/xJ1ZA6X3GEf4sNReNAtaucPEelgR2nsN0gKQKBiGoqHWbK1qYvBxX2X3kbPDkv -9C+celgZd2PW7aGYLCHq7nPbmfDV0yHcWjOhXZ8jRMjmANVR/eLQ2EfsRLdW69bn -f3ZD7JS1fwGnO3exGmHO3HZG+6AvberKYVYNHahNFEw5TsAcQWDLRpkGybBcxqZo -81YCqlqidwfeO5YtlO7etx1xLyqa2NsCeG9A86UjG+aeNnXEIDk1PDK+EuiThIUa -/2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQYgTImOlfW6/GuYIxKYgEKCFHFqJATAG -IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8CxaEMQoevxAta0ssMK3w6UsDtvUvYvF22m -qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLgsnrtUPZx+z2Ep2x0xc5orneB5fGyF1P -WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTxcjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ -EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRDs15M38eG2cYwB1PZpDHScDnDA0= ------END RSA PRIVATE KEY----- -¶ -
The same public and private keypair in JWK format:¶
--NOTE: '\' line wrapping per RFC 8792 - -{ - "kty": "RSA", - "kid": "test-key-rsa", - "p": "sqeUJmqXE3LP8tYoIjMIAKiTm9o6psPlc8CrLI9CH0UbuaA2JCOMcCNq8Sy\ - YbTqgnWlB9ZfcAm_cFpA8tYci9m5vYK8HNxQr-8FS3Qo8N9RJ8d0U5CswDzMYfRgh\ - AfUGwmlWj5hp1pQzAuhwbOXFtxKHVsMPhz1IBtF9Y8jvgqgYHLbmyiu1mw", - "q": "vSlgXQbvHzWmuUBFRHAejRh_naQTDV3GnH4lcRHuFBFZCSLn82xQS2_7xFO\ - qfabqq17kNcvKfzdvWpGxxJ2cILAq0pZS6DmrZlvBU4IkK2ZHCac_XfWVZFh-PrsH\ - _EnVkDpfcYR_iw1F40C1q5w8R6WBHaew3SAp", - "d": "b8lm5JZ2hUduLnq-OAKCSODeWQ7Uqs7eet2bqeuAD0_2po-PG4qhZoo7VwF\ - CUTWlJan9wqdxiAPlbEQKkCdFRcbakbjN2TMJjMCHWL5zfgvqhmgeyKsrqg1wSce9\ - 7J1_Mkvn3fh6CbqnwNb6bVFDvTJS3i5FzRhKiv6rUsYm8ZAdF4XRaYkFkeuHPl7rc\ - -ruUTSAjC4GovxIxoDJFe0r4kbFmkiZOr40e8RZYK7T1IKrSvzfxx5AjnlK_OZOTC\ - q0L7wBPbMW-IxmQpFCjpI-yuoi3FlZG3LaLNrBMXQF_lLZUDHs77q3fAGxDWwum2h\ - KBfdBuUQtjlqwjQlgXPsskQ", - "e": "AQAB", - "qi": "PkbARLOwU_LcZrQy9mmfcPoQlAuCyeu1Q9nH7PYSnbHTFzmiud4Hl8bIXU\ - 9a0_58blDoOl3PctF-b4rAEJYUpCODu5PFyN6uEFYRg-YQwpjBMkXk8Eb39128ctA\ - RB40Lx8caDhRdTyaEedIG3cQDXSpAl9EOzXkzfx4bZxjAHU9mkMdJwOcMDQ", - "dp": "aiodZsrWpi8HFfZfeRs8OS_0L5x6WBl3Y9btoZgsIeruc9uZ8NXTIdxaM6\ - FdnyNEyOYA1VH94tDYR-xEt1br1ud_dkPslLV_Aac7d7EaYc7cdkb7oC9t6sphVg0\ - dqE0UTDlOwBxBYMtGmQbJsFzGpmjzVgKqWqJ3B947li2U7t63HXEvKprY2w", - "dq": "b0DzpSMb5p42dcQgOTU8Mr4S6JOEhRr_YjErMkpaXUEqvZ3jEB9HRmcRi5\ - Gtt4NBiBMiY6V9br8a5gjEpiAQoIUcWokBMAYjEeurU8M6JLBd3YaZVVjISaFmdty\ - nwLFoQxCh6_EC1rSywwrfDpSwO29S9i8Xbaap", - "n": "hAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrwWEBnez6\ - d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFqMGmXCQvE\ - G7YemcxDTRPxAleIAgYYRjTSd_QBwVW9OwNFhekro3RtlinV0a75jfZgkne_YiktS\ - vLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0PuKxI4T-HIa\ - Fpv8-rdV6eUgOrB2xeI1dSFFn_nnv5OoZJEIB-VmuKn3DCUcCZSFlQPSXSfBDiUGh\ - wOw76WuSSsf1D4b_vLoJ10w" -} -¶ -
The following key is a 2048-bit RSA public and private key pair, referred to in this document
-as test-key-rsa-pss
. This key is PCKS#8 encoded in PEM format, with no encryption.¶
------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2 -+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+ -oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq -gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W -Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4 -aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI -2wIDAQAB ------END PUBLIC KEY----- - ------BEGIN PRIVATE KEY----- -MIIEvgIBADALBgkqhkiG9w0BAQoEggSqMIIEpgIBAAKCAQEAr4tmm3r20Wd/Pbqv -P1s2+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry5 -3mm+oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7Oyr -FAHqgDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUA -AN5WUtzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw -9lq4aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oy -c6XI2wIDAQABAoIBAQCUB8ip+kJiiZVKF8AqfB/aUP0jTAqOQewK1kKJ/iQCXBCq -pbo360gvdt05H5VZ/RDVkEgO2k73VSsbulqezKs8RFs2tEmU+JgTI9MeQJPWcP6X -aKy6LIYs0E2cWgp8GADgoBs8llBq0UhX0KffglIeek3n7Z6Gt4YFge2TAcW2WbN4 -XfK7lupFyo6HHyWRiYHMMARQXLJeOSdTn5aMBP0PO4bQyk5ORxTUSeOciPJUFktQ -HkvGbym7KryEfwH8Tks0L7WhzyP60PL3xS9FNOJi9m+zztwYIXGDQuKM2GDsITeD -2mI2oHoPMyAD0wdI7BwSVW18p1h+jgfc4dlexKYRAoGBAOVfuiEiOchGghV5vn5N -RDNscAFnpHj1QgMr6/UG05RTgmcLfVsI1I4bSkbrIuVKviGGf7atlkROALOG/xRx -DLadgBEeNyHL5lz6ihQaFJLVQ0u3U4SB67J0YtVO3R6lXcIjBDHuY8SjYJ7Ci6Z6 -vuDcoaEujnlrtUhaMxvSfcUJAoGBAMPsCHXte1uWNAqYad2WdLjPDlKtQJK1diCm -rqmB2g8QE99hDOHItjDBEdpyFBKOIP+NpVtM2KLhRajjcL9Ph8jrID6XUqikQuVi -4J9FV2m42jXMuioTT13idAILanYg8D3idvy/3isDVkON0X3UAVKrgMEne0hJpkPL -FYqgetvDAoGBAKLQ6JZMbSe0pPIJkSamQhsehgL5Rs51iX4m1z7+sYFAJfhvN3Q/ -OGIHDRp6HjMUcxHpHw7U+S1TETxePwKLnLKj6hw8jnX2/nZRgWHzgVcY+sPsReRx -NJVf+Cfh6yOtznfX00p+JWOXdSY8glSSHJwRAMog+hFGW1AYdt7w80XBAoGBAImR -NUugqapgaEA8TrFxkJmngXYaAqpA0iYRA7kv3S4QavPBUGtFJHBNULzitydkNtVZ -3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE -t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND -dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF -S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR -rOjr9w349JooGXhOxbu8nOxX ------END PRIVATE KEY----- -¶ -
The same public and private keypair in JWK format:¶
--NOTE: '\' line wrapping per RFC 8792 - -{ - "kty": "RSA", - "kid": "test-key-rsa-pss", - "p": "5V-6ISI5yEaCFXm-fk1EM2xwAWekePVCAyvr9QbTlFOCZwt9WwjUjhtKRus\ - i5Uq-IYZ_tq2WRE4As4b_FHEMtp2AER43IcvmXPqKFBoUktVDS7dThIHrsnRi1U7d\ - HqVdwiMEMe5jxKNgnsKLpnq-4NyhoS6OeWu1SFozG9J9xQk", - "q": "w-wIde17W5Y0Cphp3ZZ0uM8OUq1AkrV2IKauqYHaDxAT32EM4ci2MMER2nI\ - UEo4g_42lW0zYouFFqONwv0-HyOsgPpdSqKRC5WLgn0VXabjaNcy6KhNPXeJ0Agtq\ - diDwPeJ2_L_eKwNWQ43RfdQBUquAwSd7SEmmQ8sViqB628M", - "d": "lAfIqfpCYomVShfAKnwf2lD9I0wKjkHsCtZCif4kAlwQqqW6N-tIL3bdOR-\ - VWf0Q1ZBIDtpO91UrG7pansyrPERbNrRJlPiYEyPTHkCT1nD-l2isuiyGLNBNnFoK\ - fBgA4KAbPJZQatFIV9Cn34JSHnpN5-2ehreGBYHtkwHFtlmzeF3yu5bqRcqOhx8lk\ - YmBzDAEUFyyXjknU5-WjAT9DzuG0MpOTkcU1EnjnIjyVBZLUB5Lxm8puyq8hH8B_E\ - 5LNC-1oc8j-tDy98UvRTTiYvZvs87cGCFxg0LijNhg7CE3g9piNqB6DzMgA9MHSOw\ - cElVtfKdYfo4H3OHZXsSmEQ", - "e": "AQAB", - "qi": "jRAqfYi_tKCjhP9eM0N2XaRlNeoYCTx06GlSLD8d0zc4ZZuEePY10LMGWI\ - 6Y_JC0CvvvQYhNa9sAj4hFjIVLsWeTplVVUezGO1ofLW4kYWVpnMpHgAY1pRM4kyz\ - o1p3MKYY8DE1BA4KqhSOfhdGs6Ov3Dfj0migZeE7Fu7yc7Fc", - "dp": "otDolkxtJ7Sk8gmRJqZCGx6GAvlGznWJfibXPv6xgUAl-G83dD84YgcNGn\ - oeMxRzEekfDtT5LVMRPF4_AoucsqPqHDyOdfb-dlGBYfOBVxj6w-xF5HE0lV_4J-H\ - rI63Od9fTSn4lY5d1JjyCVJIcnBEAyiD6EUZbUBh23vDzRcE", - "dq": "iZE1S6CpqmBoQDxOsXGQmaeBdhoCqkDSJhEDuS_dLhBq88FQa0UkcE1QvO\ - K3J2Q21VnfDqGBx7SH1hOFOj-cpz45kNluB832ztxDvnHQ9AIA7h_HY_3VD6YPMNR\ - VN4bfSYS3abdLR0Z7jsmInGJ9X0_fA0E2tkZIgXeas5EFU0M", - "n": "r4tmm3r20Wd_PbqvP1s2-QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvM\ - s8ct-Lh1GH45x28Rw3Ry53mm-oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95An\ - dTrifbIFPNU8PPMO7OyrFAHqgDsznjPFmTOtCEcN2Z1FpWgchwuYLPL-Wokqltd11\ - nqqzi-bJ9cvSKADYdUAAN5WUtzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSy\ - ZYoA485mqcO0GVAdVw9lq4aOT9v6d-nb4bnNkQVklLQ3fVAvJm-xdDOp9LCNCN48V\ - 2pnDOkFV6-U9nV5oyc6XI2w" -} -¶ -
The following key is a public and private elliptical curve key pair over the curve P-256, referred -to in this document as `test-key-ecc-p256. This key is encoded in PEM format, with no encryption.¶
-------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lf -w0EkjqF7xB4FivAxzic30tMM4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== ------END PUBLIC KEY----- - ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIFKbhfNZfpDsW43+0+JjUr9K+bTeuxopu653+hBaXGA7oAoGCCqGSM49 -AwEHoUQDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lfw0EkjqF7xB4FivAxzic30tMM -4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== ------END EC PRIVATE KEY----- -¶ -
The same public and private keypair in JWK format:¶
--{ - "kty": "EC", - "crv": "P-256", - "kid": "test-key-ecc-p256", - "d": "UpuF81l-kOxbjf7T4mNSv0r5tN67Gim7rnf6EFpcYDs", - "x": "qIVYZVLCrPZHGHjP17CTW0_-D9Lfw0EkjqF7xB4FivA", - "y": "Mc4nN9LTDOBhfoUeg8Ye9WedFRhnZXZJA12Qp0zZ6F0" -} -¶ -
The following key is an elliptical curve key over the Edwards curve ed25519, referred to in this document as test-key-ed25519
. This key is PCKS#8 encoded in PEM format, with no encryption.¶
------BEGIN PUBLIC KEY----- -MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs= ------END PUBLIC KEY----- - ------BEGIN PRIVATE KEY----- -MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF ------END PRIVATE KEY----- -¶ -
The same public and private keypair in JWK format:¶
--{ - "kty": "OKP", - "crv": "Ed25519", - "kid": "test-key-ed25519", - "d": "n4Ni-HpISpVObnQMW0wOhCKROaIKqKtW_2ZYb2p9KcU", - "x": "JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs" -} -¶ -
This section provides non-normative examples that may be used as test cases to validate implementation correctness. These examples are based on the following HTTP messages:¶
-For requests, this test-request
message is used:¶
For responses, this test-response
message is used:¶
This example presents a minimal signature using the rsa-pss-sha512
algorithm over test-request
, covering none
-of the components of the HTTP message, but providing a timestamped signature proof of possession of the key with a signer-provided nonce.¶
The corresponding signature base is:¶
--NOTE: '\' line wrapping per RFC 8792 - -"@signature-params": ();created=1618884473;keyid="test-key-rsa-pss"\ - ;nonce="b3k2pp5k7z-50gnwp.yemd" -¶ -
This results in the following Signature-Input and Signature header fields being added to the message under the signature label sig-b21
:¶
Note that since the covered components list is empty, this signature could be applied by an attacker to an unrelated HTTP message. In this example, the nonce
parameter is included to prevent the same signature from being replayed more than once, but if an attacker intercepts the signature and prevents its delivery to the verifier, the attacker could apply this signature to another message. Therefore, use of an empty covered components set is discouraged. See Section 7.2.1 for more discussion.¶
Note that the RSA PSS algorithm in use here is non-deterministic, meaning a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly-generated signature values are not expected to match the example. See Section 7.3.5.¶
-This example covers additional components (the authority, the Content-Digest header field, and a single named query parameter) in test-request
using the rsa-pss-sha512
algorithm. This example also adds a tag
parameter with the application-specific value of header-example
.¶
The corresponding signature base is:¶
--NOTE: '\' line wrapping per RFC 8792 - -"@authority": example.com -"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ - +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: -"@query-param";name="Pet": dog -"@signature-params": ("@authority" "content-digest" \ - "@query-param";name="Pet")\ - ;created=1618884473;keyid="test-key-rsa-pss"\ - ;tag="header-example" -¶ -
This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b22
:¶
Note that the RSA PSS algorithm in use here is non-deterministic, meaning a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly-generated signature values are not expected to match the example. See Section 7.3.5.¶
-This example covers all applicable message components in test-request
(including the content type and length) plus many derived components, again using the rsa-pss-sha512
algorithm. Note that the Host
header field is not covered because the @authority
derived component is included instead.¶
The corresponding signature base is:¶
--NOTE: '\' line wrapping per RFC 8792 - -"date": Tue, 20 Apr 2021 02:07:55 GMT -"@method": POST -"@path": /foo -"@query": ?param=Value&Pet=dog -"@authority": example.com -"content-type": application/json -"content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ - +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: -"content-length": 18 -"@signature-params": ("date" "@method" "@path" "@query" \ - "@authority" "content-type" "content-digest" "content-length")\ - ;created=1618884473;keyid="test-key-rsa-pss" -¶ -
This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b23
:¶
Note in this example that the value of the Date
header and the value of the created
signature parameter need not be the same. This is due to the fact that the Date
header is added when creating the HTTP Message and the created
parameter is populated when creating the signature over that message, and these two times could vary. If the Date
header is covered by the signature, it is up to the verifier to determine whether its value has to match that of the created
parameter or not. See Section 7.2.4 for more discussion.¶
Note that the RSA PSS algorithm in use here is non-deterministic, meaning a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly-generated signature values are not expected to match the example. See Section 7.3.5.¶
-This example covers portions of the test-response
response message using the ecdsa-p256-sha256
algorithm
-and the key test-key-ecc-p256
.¶
The corresponding signature base is:¶
--NOTE: '\' line wrapping per RFC 8792 - -"@status": 200 -"content-type": application/json -"content-digest": sha-512=:mEWXIS7MaLRuGgxOBdODa3xqM1XdEvxoYhvlCFJ4\ - 1QJgJc4GTsPp29l5oGX69wWdXymyU0rjJuahq4l5aGgfLQ==: -"content-length": 23 -"@signature-params": ("@status" "content-type" "content-digest" \ - "content-length");created=1618884473;keyid="test-key-ecc-p256" -¶ -
This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b24
:¶
Note that the ECDSA algorithm in use here is non-deterministic, meaning a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly-generated signature values are not expected to match the example. See Section 7.3.5.¶
-This example covers portions of the test-request
using the hmac-sha256
algorithm and the
-secret test-shared-secret
.¶
The corresponding signature base is:¶
--NOTE: '\' line wrapping per RFC 8792 - -"date": Tue, 20 Apr 2021 02:07:55 GMT -"@authority": example.com -"content-type": application/json -"@signature-params": ("date" "@authority" "content-type")\ - ;created=1618884473;keyid="test-shared-secret" -¶ -
This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b25
:¶
Before using symmetric signatures in practice, see the discussion of the security tradeoffs in Section 7.3.3.¶
-This example covers portions of the test-request
using the ed25519
algorithm
-and the key test-key-ed25519
.¶
The corresponding signature base is:¶
--NOTE: '\' line wrapping per RFC 8792 - -"date": Tue, 20 Apr 2021 02:07:55 GMT -"@method": POST -"@path": /foo -"@authority": example.com -"content-type": application/json -"content-length": 18 -"@signature-params": ("date" "@method" "@path" "@authority" \ - "content-type" "content-length");created=1618884473\ - ;keyid="test-key-ed25519" -¶ -
This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b26
:¶
In this example, there is a TLS-terminating reverse proxy sitting in front of the resource. The client does not sign the request but instead uses mutual TLS to make its call. The terminating proxy validates the TLS stream and injects a Client-Cert
header according to [CLIENT-CERT], and then applies a signature to this field. By signing this header field, a reverse proxy can not only attest to its own validation of the initial request's TLS parameters but also authenticate itself to the backend system independently of the client's actions.¶
The client makes the following request to the TLS terminating proxy using mutual TLS:¶
- -The proxy processes the TLS connection and extracts the client's TLS certificate to a Client-Cert
header field and passes it along to the internal service hosted at service.internal.example
. This results in the following unsigned request:¶
Without a signature, the internal service would need to trust that the incoming connection has the right information. By signing the Client-Cert
header and other portions of the internal request, the internal service can be assured that the correct party, the trusted proxy, has processed the request and presented it to the correct service. The proxy's signature base consists of the following:¶
-NOTE: '\' line wrapping per RFC 8792 - -"@path": /foo -"@query": ?param=Value&Pet=dog -"@method": POST -"@authority": service.internal.example -"client-cert": :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQ\ - KDBJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBD\ - QTAeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDM\ - FkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXm\ - ckC8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQY\ - DVR0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8B\ - Af8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQ\ - GV4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0\ - Q6bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: -"@signature-params": ("@path" "@query" "@method" "@authority" \ - "client-cert");created=1618884473;keyid="test-key-ecc-p256" -¶ -
This results in the following signature:¶
--NOTE: '\' line wrapping per RFC 8792 - -xVMHVpawaAC/0SbHrKRs9i8I3eOs5RtTMGCWXm/9nvZzoHsIg6Mce9315T6xoklyy0y\ -zhD9ah4JHRwMLOgmizw== -¶ -
Which results in the following signed request sent from the proxy to the internal service with the proxy's signature under the label ttrp
:¶
-NOTE: '\' line wrapping per RFC 8792 - -POST /foo?param=Value&Pet=dog HTTP/1.1 -Host: service.internal.example -Date: Tue, 20 Apr 2021 02:07:55 GMT -Content-Type: application/json -Content-Length: 18 -Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ - BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ - AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ - wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ - C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ - R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ - 8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ - 4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ - bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: -Signature-Input: ttrp=("@path" "@query" "@method" "@authority" \ - "client-cert");created=1618884473;keyid="test-key-ecc-p256" -Signature: ttrp=:xVMHVpawaAC/0SbHrKRs9i8I3eOs5RtTMGCWXm/9nvZzoHsIg6\ - Mce9315T6xoklyy0yzhD9ah4JHRwMLOgmizw==: - -{"hello": "world"} -¶ -
The internal service can validate the proxy's signature and therefore be able to trust that the client's certificate has been appropriately processed.¶
-The HTTP protocol allows intermediaries and applications to transform an HTTP message without affecting the semantics of the message itself. HTTP message signatures are designed to be robust against many of these transformations in different circumstances.¶
-For example, the following HTTP request message has been signed using the ed25519
algorithm
-and the key test-key-ed25519
.¶
The signature base string for this message is:¶
--"@method": GET -"@path": /demo -"@authority": example.org -"accept": application/json, */* -"@signature-params": ("@method" "@path" "@authority" "accept")\ - ;created=1618884473;keyid="test-key-ed25519" -¶ -
The following message has been altered by adding the Accept-Language header as well as adding a query parameter. However, since neither the Accept-Language header nor the query are covered by the signature, the same signature is still valid:¶
- -The following message has been altered by removing the Date header, adding a Referer header, and collapsing the Accept header into a single line. The Date and Referrer headers are not covered by the signature, and the collapsing of the Accept header is an allowed transformation that is already accounted for by the canonicalization algorithm for HTTP field values. The same signature is still valid:¶
- -The following message has been altered by re-ordering the field values of the original message, but not re-ordering the individual Accept headers. The same signature is still valid:¶
- -The following message has been altered by changing the method to POST and the authority to "example.com" (inside the Host header). Since both the method and authority are covered by the signature, the same signature is NOT still valid:¶
- -The following message has been altered by changing the order of the two instances of the Accept header. Since the order of fields with the same name is semantically significant in HTTP, this changes the value used in the signature base, and the same signature is NOT still valid:¶
- -This specification was initially based on the [I-D.cavage-http-signatures] internet draft. The editors would like to thank the authors of that draft, Mark Cavage and Manu Sporny, for their work on that draft and their continuing contributions. The specification also includes contributions from the [I-D.ietf-oauth-signed-http-request] internet draft and other similar efforts.¶
-The editors would also like to thank the following individuals for feedback, insight, and implementation of this draft and its predecessors (in alphabetical order): -Mark Adamcin, -Mark Allen, -Paul Annesley, -Karl Böhlmark, -Stéphane Bortzmeyer, -Sarven Capadisli, -Liam Dennehy, -Stephen Farrell, -Phillip Hallam-Baker, -Tyler Ham, -Eric Holmes, -Andrey Kislyuk, -Adam Knight, -Dave Lehn, -Dave Longley, -Ilari Liusvaara, -James H. Manger, -Kathleen Moriarty, -Mark Nottingham, -Yoav Nir, -Adrian Palmer, -Lucas Pardue, -Roberto Polli, -Julian Reschke, -Michael Richardson, -Wojciech Rygielski, -Rich Salz, -Adam Scarr, -Cory J. Slep, -Dirk Stein, -Henry Story, -Lukasz Szewc, -Chris Webber, and -Jeffrey Yasskin.¶
-RFC EDITOR: please remove this section before publication¶
-draft-ietf-httpbis-message-signatures¶
--19¶
-Update IANA registration instructions.¶
--18¶
- --17¶
-Change encoding¶
-Remove sign-the-signature examples and add explanations of why not to do that.¶
-Query parameter values must be re-encoded for safety.¶
-Query parameters now carry a warning of limitations.¶
-Address field value encodings.¶
-Discuss history and positioning of this specification.¶
-Import obs-fold, reference US-ASCII, enforce ASCII-ness of Signature Base¶
--16¶
-Editorial cleanup from AD review.¶
-Clarified dependency on structured field serialization rules.¶
-Define use of all parameters in Accept-Signature.¶
-Update example signature calculations.¶
-Clarify how combined fields are handled.¶
-Add more detailed instructions for IANA DE's.¶
-Fix some references and anchors.¶
--15¶
- --14¶
-Target raw non-decoded values for "@query" and "@path".¶
-Add method for signing trailers.¶
-Call out potential issues of list-based field values.¶
-Update IANA registry for header fields.¶
-Call out potential issues with Content-Digest in example.¶
-Add JWK formats for all keys.¶
--13¶
- --12¶
- --11¶
- --10¶
- --09¶
- --08¶
- --07¶
-Added security and privacy considerations.¶
-Added pointers to algorithm values from definition sections.¶
-Expanded IANA registry sections.¶
-Clarified that the signing and verification algorithms take application requirements as inputs.¶
-Defined "signature targets" of request, response, and related-response for specialty components.¶
--06¶
-Updated language for message components, including identifiers and values.¶
-Clarified that Signature-Input and Signature are fields which can be used as headers or trailers.¶
-Add "Accept-Signature" field and semantics for signature negotiation.¶
-Define new specialty content identifiers, re-defined request-target identifier.¶
-Added request-response binding.¶
--05¶
- --04¶
- --03¶
-Clarified signing and verification processes.¶
-Updated algorithm and key selection method.¶
-Clearly defined core algorithm set.¶
-Defined JOSE signature mapping process.¶
-Removed legacy signature methods.¶
-Define signature parameters separately from "signature" object model.¶
-Define serialization values for signature-input header based on signature input.¶
--02¶
-Removed editorial comments on document sources.¶
-Removed in-document issues list in favor of tracked issues.¶
-Replaced unstructured Signature
header with Signature-Input
and Signature
Dictionary Structured Header Fields.¶
Defined content identifiers for individual Dictionary members, e.g., "x-dictionary-field";key=member-name
.¶
Defined content identifiers for first N members of a List, e.g., "x-list-field":prefix=4
.¶
Fixed up examples.¶
-Updated introduction now that it's adopted.¶
-Defined specialty content identifiers and a means to extend them.¶
-Required signature parameters to be included in signature.¶
-Added guidance on backwards compatibility, detection, and use of signature methods.¶
--01¶
- --00¶
-Initialized from draft-richanna-http-message-signatures-00, following adoption by the working group.¶
-draft-richanna-http-message-signatures¶
--00¶
-Converted to xml2rfc v3 and reformatted to comply with RFC style guides.¶
-Removed Signature auth-scheme definition and related content.¶
-Removed conflicting normative requirements for use of algorithm parameter. Now MUST NOT be relied upon.¶
-Removed Extensions appendix.¶
-Rewrote abstract and introduction to explain context and need, and challenges inherent in signing HTTP messages.¶
-Rewrote and heavily expanded algorithm definition, retaining normative requirements.¶
-Added definitions for key terms, referenced RFC 7230 for HTTP terms.¶
-Added examples for canonicalization and signature generation steps.¶
-Rewrote Signature header definition, retaining normative requirements.¶
-Added default values for algorithm and expires parameters.¶
-Rewrote HTTP Signature Algorithms registry definition. Added change control policy and registry template. Removed suggested URI.¶
-Added IANA HTTP Signature Parameter registry.¶
-Added additional normative and informative references.¶
-Added Topics for Working Group Discussion section, to be removed prior to publication as an RFC.¶
-Internet-Draft | -Resumable Uploads | -January 2024 | -
Kleidl, et al. | -Expires 27 July 2024 | -[Page] | -
HTTP clients often encounter interrupted data transfers as a result of canceled requests or dropped connections. Prior to interruption, part of a representation may have been exchanged. To complete the data transfer of the entire representation, it is often desirable to issue subsequent requests that transfer only the remainder of the representation. HTTP range requests support this concept of resumable downloads from server to client. This document describes a mechanism that supports resumable uploads from client to server using HTTP.¶
-This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-resumable-upload/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/resumable-upload.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-HTTP clients often encounter interrupted data transfers as a result of canceled requests or dropped connections. Prior to interruption, part of a representation (see Section 3.2 of [HTTP]) might have been exchanged. To complete the data transfer of the entire representation, it is often desirable to issue subsequent requests that transfer only the remainder of the representation. HTTP range requests (see Section 14 of [HTTP]) support this concept of resumable downloads from server to client.¶
-HTTP methods such as POST or PUT can be used by clients to request processing of representation data enclosed in the request message. The transfer of representation data from client to server is often referred to as an upload. Uploads are just as likely as downloads to suffer from the effects of data transfer interruption. Humans can play a role in upload interruptions through manual actions such as pausing an upload. Regardless of the cause of an interruption, servers may have received part of the representation before its occurrence and it is desirable if clients can complete the data transfer by sending only the remainder of the representation. The process of sending additional parts of a representation using subsequent HTTP requests from client to server is herein referred to as a resumable upload.¶
-Connection interruptions are common and the absence of a standard mechanism for resumable uploads has lead to a proliferation of custom solutions. Some of those use HTTP, while others rely on other transfer mechanisms entirely. An HTTP-based standard solution is desirable for such a common class of problem.¶
-This document defines an optional mechanism for HTTP that enables resumable uploads in a way that is backwards-compatible with conventional HTTP uploads. When an upload is interrupted, clients can send subsequent requests to query the server state and use this information to send the remaining data. Alternatively, they can cancel the upload entirely. Different from ranged downloads, this protocol does not support transferring different parts of the same representation in parallel.¶
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", -"MAY", and "OPTIONAL" in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here.¶
-The terms Byte Sequence, Item, String, Token, Integer, and Boolean are imported from -[STRUCTURED-FIELDS].¶
- -Resumable uploads are supported in HTTP through use of a temporary resource, an upload resource, that is separate from the resource being uploaded to (hereafter, the target resource) and specific to that upload. By interacting with the upload resource, a client can retrieve the current offset of the upload (Section 5), append to the upload (Section 6), and cancel the upload (Section 7).¶
-The remainder of this section uses an example of a file upload to illustrate different interactions with the upload resource. Note, however, that HTTP message exchanges use representation data (see Section 8.1 of [HTTP]), which means that resumable uploads can be used with many forms of content -- not just static files.¶
-In this example, the client first attempts to upload a file with a known size in a single HTTP request to the target resource. An interruption occurs and the client then attempts to resume the upload using subsequent HTTP requests to the upload resource.¶
-1) The client notifies the server that it wants to begin an upload (Section 4). The server reserves the required resources to accept the upload from the client, and the client begins transferring the entire file in the request content.¶
-An informational response can be sent to the client, which signals the server's support of resumable upload as well as the upload resource URL via the Location header field (Section 10.2.2 of [HTTP]).¶
-2) If the connection to the server is interrupted, the client might want to resume the upload. However, before this is possible the client needs to know the amount of data that the server received before the interruption. It does so by retrieving the offset (Section 5) from the upload resource.¶
-3) The client can resume the upload by sending the remaining file content to the upload resource (Section 6), appending to the already stored data in the upload. The Upload-Offset
value is included to ensure that the client and server agree on the offset that the upload resumes from.¶
4) If the client is not interested in completing the upload, it can instruct the upload resource to delete the upload and free all related resources (Section 7).¶
-In some cases, clients might prefer to upload a file as a series of parts sent serially across multiple HTTP messages. One use case is to overcome server limits on HTTP message content size. Another use case is where the client does not know the final size, such as when file data originates from a streaming source.¶
-This example shows how the client, with prior knowledge about the server's resumable upload support, can upload parts of a file incrementally.¶
-1) If the client is aware that the server supports resumable upload, it can start an upload with the Upload-Complete
field value set to false and the first part of the file.¶
2) Subsequently, parts are appended (Section 6). The last part of the upload has a Upload-Complete
field value set to true to indicate the complete transfer.¶
When a resource supports resumable uploads, the first step is creating the upload resource. To be compatible with the widest range of resources, this is accomplished by including the Upload-Complete
header field in the request that initiates the upload.¶
As a consequence, resumable uploads support all HTTP request methods that can carry content, such as POST
, PUT
, and PATCH
. Similarly, the response to the upload request can have any status code. Both the method(s) and status code(s) supported are determined by the resource.¶
Upload-Complete
MUST be set to false if the end of the request content is not the end of the upload. Otherwise, it MUST be set to true. This header field can be used for request identification by a server. The request MUST NOT include the Upload-Offset
header field.¶
If the request is valid, the server SHOULD create an upload resource. Then, the server MUST include the Location
header field in the response and set its value to the URL of the upload resource. The client MAY use this URL for offset retrieval (Section 5), upload append (Section 6), and upload cancellation (Section 7).¶
Once the upload resource is available and while the request content is being uploaded, the target resource MAY send one or more informational responses with a 104 (Upload Resumption Supported)
status code to the client. In the first informational response, the Location
header field MUST be set to the URL pointing to the upload resource. In subsequent informational responses, the Location
header field MUST NOT be set. An informational response MAY contain the Upload-Offset
header field with the current upload offset as the value to inform the client about the upload progress. In subsequent informational responses, the upload offset MUST NOT be smaller than in previous informational responses. In addition, later offset retrievals (Section 5) MUST NOT receive an upload offset that is less than the offset reported in the latest informational response, allowing the client to free associated resources.¶
The server MUST send the Upload-Offset
header field in the response if it considers the upload active, either when the response is a success (e.g. 201 (Created)
), or when the response is a failure (e.g. 409 (Conflict)
). The Upload-Offset
field value MUST be equal to the end offset of the entire upload, or the begin offset of the next chunk if the upload is still incomplete. The client SHOULD consider the upload failed if the response has a status code that indicates a success but the offset indicated in the Upload-Offset
field value does not equal the total of begin offset plus the number of bytes uploaded in the request.¶
If the request completes successfully and the entire upload is complete, the server MUST acknowledge it by responding with a successful status code between 200 and 299 (inclusive). Servers are RECOMMENDED to use 201 (Created)
unless otherwise specified. The response MUST NOT include the Upload-Complete
header field with the value of false.¶
If the request completes successfully but the entire upload is not yet complete, as indicated by an Upload-Complete
field value of false in the request, the server MUST acknowledge it by responding with the 201 (Created)
status code and an Upload-Complete
header value set to false.¶
If the request includes an Upload-Complete
field value set to true and a valid Content-Length
header field, the client attempts to upload a fixed-length resource in one request. In this case, the upload's final size is the Content-Length
field value and the server MUST record it to ensure its consistency.¶
If the client received an informational response with the upload URL in the Location field value, it MAY automatically attempt upload resumption when the connection is terminated unexpectedly, or if a 5xx status is received. The client SHOULD NOT automatically retry if it receives a 4xx status code.¶
-File metadata can affect how servers might act on the uploaded file. Clients can send representation metadata (see Section 8.3 of [HTTP]) in the request that starts an upload. Servers MAY interpret this metadata or MAY ignore it. The Content-Type
header field (Section 8.3 of [HTTP]) can be used to indicate the MIME type of the file. The Content-Disposition
header field ([RFC6266]) can be used to transmit a filename; if included, the parameters SHOULD be either filename
, filename*
or boundary
.¶
If the client has no knowledge of whether the resource supports resumable uploads, a resumable request can be used with some additional constraints. In particular, the Upload-Complete
field value (Section 8.2) MUST NOT be false if the server support is unclear. This allows the upload to function as if it is a regular upload.¶
Servers SHOULD use the 104 (Upload Resumption Supported)
informational response to indicate their support for a resumable upload request.¶
Clients MUST NOT attempt to resume an upload unless they receive 104 (Upload Resumption Supported)
informational response, or have other out-of-band methods to determine server support for resumable uploads.¶
RFC Editor's Note: Please remove this section and Upload-Draft-Interop-Version
from all examples prior to publication of a final version of this document.¶
The current interop version is 4.¶
-Client implementations of draft versions of the protocol MUST send a header field Upload-Draft-Interop-Version
with the interop version as its value to its requests. The Upload-Draft-Interop-Version
field value is an Integer.¶
Server implementations of draft versions of the protocol MUST NOT send a 104 (Upload Resumption Supported)
informational response when the interop version indicated by the Upload-Draft-Interop-Version
header field in the request is missing or mismatching.¶
Server implementations of draft versions of the protocol MUST also send a header field Upload-Draft-Interop-Version
with the interop version as its value to the 104 (Upload Resumption Supported)
informational response.¶
Client implementations of draft versions of the protocol MUST ignore a 104 (Upload Resumption Supported)
informational response with missing or mismatching interop version indicated by the Upload-Draft-Interop-Version
header field.¶
The reason both the client and the server are sending and checking the draft version is to ensure that implementations of the final RFC will not accidentally interop with draft implementations, as they will not check the existence of the Upload-Draft-Interop-Version
header field.¶
If an upload is interrupted, the client MAY attempt to fetch the offset of the incomplete upload by sending a HEAD
request to the upload resource.¶
The request MUST NOT include an Upload-Offset
or Upload-Complete
header field. The server MUST reject requests with either of these fields by responding with a 400 (Bad Request)
status code.¶
If the server considers the upload resource to be active, it MUST respond with a 204 (No Content)
status code. The response MUST include the Upload-Offset
header field, with the value set to the current resumption offset for the target resource. The response MUST include the Upload-Complete
header field; the value is set to true only if the upload is complete.¶
An upload is considered complete only if the server completely and successfully received a corresponding creation request (Section 4) or append request (Section 6) with the Upload-Complete
header value set to true.¶
The client MUST NOT perform offset retrieval while creation (Section 4) or append (Section 6) is in progress.¶
-The offset MUST be accepted by a subsequent append (Section 6). Due to network delay and reordering, the server might still be receiving data from an ongoing transfer for the same upload resource, which in the client perspective has failed. The server MAY terminate any transfers for the same upload resource before sending the response by abruptly terminating the HTTP connection or stream. Alternatively, the server MAY keep the ongoing transfer alive but ignore further bytes received past the offset.¶
-The client MUST NOT start more than one append (Section 6) based on the resumption offset from a single offset retrieving (Section 5) request.¶
-In order to prevent HTTP caching, the response SHOULD include a Cache-Control
header field with the value no-store
.¶
If the server does not consider the upload resource to be active, it MUST respond with a 404 (Not Found)
status code.¶
The resumption offset can be less than or equal to the number of bytes the client has already sent. The client MAY reject an offset which is greater than the number of bytes it has already sent during this upload. The client is expected to handle backtracking of a reasonable length. If the offset is invalid for this upload, or if the client cannot backtrack to the offset and reproduce the same content it has already sent, the upload MUST be considered a failure. The client MAY cancel the upload (Section 7) after rejecting the offset.¶
- - -The client SHOULD NOT automatically retry if a client error status code between 400 and 499 (inclusive) is received.¶
-Upload appending is used for resuming an existing upload.¶
-The request MUST use the PATCH
method and be sent to the upload resource. The Upload-Offset
field value (Section 8.1) MUST be set to the resumption offset.¶
If the end of the request content is not the end of the upload, the Upload-Complete
field value (Section 8.2) MUST be set to false.¶
The server SHOULD respect representation metadata received during creation (Section 4) and ignore any representation metadata received from appending (Section 6).¶
-If the server does not consider the upload associated with the upload resource active, it MUST respond with a 404 (Not Found)
status code.¶
The client MUST NOT perform multiple upload transfers for the same upload resource in parallel. This helps avoid race conditions, and data loss or corruption. The server is RECOMMENDED to take measures to avoid parallel upload transfers: The server MAY terminate any creation (Section 4) or append (Section 6) for the same upload URL. Since the client is not allowed to perform multiple transfers in parallel, the server can assume that the previous attempt has already failed. Therefore, the server MAY abruptly terminate the previous HTTP connection or stream.¶
-If the offset indicated by the Upload-Offset
field value does not match the offset provided by the immediate previous offset retrieval (Section 5), or the end offset of the immediate previous incomplete successful transfer, the server MUST respond with a 409 (Conflict)
status code.¶
While the request content is being uploaded, the target resource MAY send one or more informational responses with a 104 (Upload Resumption Supported)
status code to the client. These informational responses MUST NOT contain the Location
header field. They MAY include the Upload-Offset
header field with the current upload offset as the value to inform the client about the upload progress. The same restrictions on the Upload-Offset
header field in informational responses from the upload creation (Section 4) apply.¶
The server MUST send the Upload-Offset
header field in the response if it considers the upload active, either when the response is a success (e.g. 201 (Created)
), or when the response is a failure (e.g. 409 (Conflict)
). The value MUST be equal to the end offset of the entire upload, or the begin offset of the next chunk if the upload is still incomplete. The client SHOULD consider the upload failed if the status code indicates a success but the offset indicated by the Upload-Offset
field value does not equal the total of begin offset plus the number of bytes uploaded in the request.¶
If the request completes successfully and the entire upload is complete, the server MUST acknowledge it by responding with a successful status code between 200 and 299 (inclusive). Servers are RECOMMENDED to use a 201 (Created)
response if not otherwise specified. The response MUST NOT include the Upload-Complete
header field with the value set to false.¶
If the request completes successfully but the entire upload is not yet complete indicated by the Upload-Complete
field value set to false, the server MUST acknowledge it by responding with a 201 (Created)
status code and the Upload-Complete
field value set to true.¶
If the request includes the Upload-Complete
field value set to true and a valid Content-Length
header field, the client attempts to upload the remaining resource in one request. In this case, the upload's final size is the sum of the upload's offset and the Content-Length
header field. If the server does not have a record of the upload's final size from creation or the previous append, the server MUST record the upload's final size to ensure its consistency. If the server does have a previous record, that value MUST match the upload's final size. If they do not match, the server MUST reject the request with a 400 (Bad Request)
status code.¶
The client MAY automatically attempt upload resumption when the connection is terminated unexpectedly, or if a server error status code between 500 and 599 (inclusive) is received. The client SHOULD NOT automatically retry if a client error status code between 400 and 499 (inclusive) is received.¶
-If the client wants to terminate the transfer without the ability to resume, it can send a DELETE
request to the upload resource. Doing so is an indication that the client is no longer interested in continuing the upload, and that the server can release any resources associated with it.¶
The client MUST NOT initiate cancellation without the knowledge of server support.¶
-The request MUST use the DELETE
method. The request MUST NOT include an Upload-Offset
or Upload-Complete
header field. The server MUST reject the request with a Upload-Offset
or Upload-Complete
header field with a 400 (Bad Request)
status code.¶
If the server successfully deactivates the upload resource, it MUST respond with a 204 (No Content)
status code.¶
The server MAY terminate any in-flight requests to the upload resource before sending the response by abruptly terminating their HTTP connection(s) or stream(s).¶
-If the server does not consider the upload resource to be active, it MUST respond with a 404 (Not Found)
status code.¶
If the server does not support cancellation, it MUST respond with a 405 (Method Not Allowed)
status code.¶
The Upload-Offset
request and response header field indicates the resumption offset of corresponding upload, counted in bytes. The Upload-Offset
field value is an Integer.¶
The Upload-Complete
request and response header field indicates whether the corresponding upload is considered complete. The Upload-Complete
field value is a Boolean.¶
The Upload-Complete
header field MUST only be used if support by the resource is known to the client (Section 4.1).¶
The 301 (Moved Permanently)
and 302 (Found)
status codes MUST NOT be used in offset retrieval (Section 5) and upload cancellation (Section 7) responses. For other responses, the upload resource MAY return a 308 (Permanent Redirect)
status code and clients SHOULD use new permanent URI for subsequent requests. If the client receives a 307 (Temporary Redirect)
response to an offset retrieval (Section 5) request, it MAY apply the redirection directly in an immediate subsequent upload append (Section 6).¶
The upload resource URL is the identifier used for modifying the upload. Without further protection of this URL, an attacker may obtain information about an upload, append data to it, or cancel it. To prevent this, the server SHOULD ensure that only authorized clients can access the upload resource. In addition, the upload resource URL SHOULD be generated in such a way that makes it hard to be guessed by unauthorized clients.¶
-Some servers or intermediaries provide scanning of content uploaded by clients. Any scanning mechanism that relies on receiving a complete file in a single request message can be defeated by resumable uploads because content can be split across multiple messages. Servers or intermediaries wishing to perform content scanning SHOULD consider how resumable uploads can circumvent scanning and take appropriate measures. Possible strategies include waiting for the upload to complete before scanning a full file, or disabling resumable uploads.¶
-IANA is asked to register the following entries in the "Hypertext Transfer Protocol (HTTP) Field Name Registry":¶
-Field Name | -Status | -Reference | -
---|---|---|
Upload-Complete | -permanent | -- Section 8.2 of this document | -
Upload-Offset | -permanent | -- Section 8.1 of this document | -
IANA is asked to register the following entry in the "HTTP Status Codes" registry:¶
- -The server is allowed to respond to upload creation (Section 4) requests with a 104 (Upload Resumption Supported)
intermediate response as soon as the server has validated the request. This way, the client knows that the server supports resumable uploads before the complete response is received. The benefit is the clients can defer starting the actual data transfer until the server indicates full support (i.e. resumable are supported, the provided upload URL is active etc).¶
On the contrary, support for intermediate responses (the 1XX
range) in existing software is limited or not at all present. Such software includes proxies, firewalls, browsers, and HTTP libraries for clients and server. Therefore, the 104 (Upload Resumption Supported)
status code is optional and not mandatory for the successful completion of an upload. Otherwise, it might be impossible in some cases to implement resumable upload servers using existing software packages. Furthermore, as parts of the current internet infrastructure currently have limited support for intermediate responses, a successful delivery of a 104 (Upload Resumption Supported)
from the server to the client should be assumed.¶
We hope that support for intermediate responses increases in the near future, to allow a wider usage of 104 (Upload Resumption Supported)
.¶
This specification includes a section about feature detection (it was called service discovery in earlier discussions, but this name is probably ill-suited). The idea is to allow resumable uploads to be transparently implemented by HTTP clients. This means that application developers just keep using the same API of their HTTP library as they have done in the past with traditional, non-resumable uploads. Once the HTTP library gets updated (e.g. because mobile OS or browsers start implementing resumable uploads), the HTTP library can transparently decide to use resumable uploads without explicit configuration by the application developer. Of course, in order to use resumable uploads, the HTTP library needs to know whether the server supports resumable uploads. If no support is detected, the HTTP library should use the traditional, non-resumable upload technique. We call this process feature detection.¶
-Ideally, the technique used for feature detection meets following criteria (there might not be one approach which fits all requirements, so we have to prioritize them):¶
-Avoid additional roundtrips by the client, if possible (i.e. an additional HTTP request by the client should be avoided).¶
-Be backwards compatible to HTTP/1.1 and existing network infrastructure: This means to avoid using new features in HTTP/2, or features which might require changes to existing network infrastructure (e.g. nginx or HTTP libraries)¶
-Conserve the user's privacy (i.e. the feature detection should not leak information to other third-parties about which URLs have been connected to)¶
-Following approaches have already been considered in the past. All except the last approaches have not been deemed acceptable and are therefore not included in the specification. This follow list is a reference for the advantages and disadvantages of some approaches:¶
-Include a support statement in the SETTINGS frame. The SETTINGS frame is a HTTP/2 feature and is sent by the server to the client to exchange information about the current connection. The idea was to include an additional statement in this frame, so the client can detect support for resumable uploads without an additional roundtrip. The problem is that this is not compatible with HTTP/1.1. Furthermore, the SETTINGS frame is intended for information about the current connection (not bound to a request/response) and might not be persisted when transmitted through a proxy.¶
-Include a support statement in the DNS record. The client can detect support when resolving a domain name. Of course, DNS is not semantically the correct layer. Also, DNS might not be involved if the record is cached or retrieved from a hosts files.¶
-Send a HTTP request to ask for support. This is the easiest approach where the client sends an OPTIONS request and uses the response to determine if the server indicates support for resumable uploads. An alternative is that the client sends the request to a well-known URL to obtain this response, e.g. /.well-known/resumable-uploads
. Of course, while being fully backwards-compatible, it requires an additional roundtrip.¶
Include a support statement in previous responses. In many cases, the file upload is not the first time that the client connects to the server. Often additional requests are sent beforehand for authentication, data retrieval etc. The responses for those requests can also include a header field which indicates support for resumable uploads. There are two options:
-- Use the standardized Alt-Svc
response header field. However, it has been indicated to us that this header field might be reworked in the future and could also be semantically different from our intended usage.
-- Use a new response header field Resumable-Uploads: https://example.org/files/*
to indicate under which endpoints support for resumable uploads is available.¶
Send a 104 intermediate response to indicate support. The clients normally starts a traditional upload and includes a header field indicate that it supports resumable uploads (e.g. Upload-Offset: 0
). If the server also supports resumable uploads, it will immediately respond with a 104 intermediate response to indicate its support, before further processing the request. This way the client is informed during the upload whether it can resume from possible connection errors or not. While an additional roundtrip is avoided, the problem with that solution is that many HTTP server libraries do not support sending custom 1XX responses and that some proxies may not be able to handle new 1XX status codes correctly.¶
Send a 103 Early Hint response to indicate support. This approach is the similar to the above one, with one exception: Instead of a new 104 (Upload Resumption Supported)
status code, the existing 103 (Early Hint)
status code is used in the intermediate response. The 103 code would then be accompanied by a header field indicating support for resumable uploads (e.g. Resumable-Uploads: 1
). It is unclear whether the Early Hints code is appropriate for that, as it is currently only used to indicate resources for prefetching them.¶
When an upload is created (Section 4), the Content-Type
and Content-Disposition
header fields are allowed to be included. They are intended to be a standardized way of communicating the file name and file type, if available. However, this is not without controversy. Some argue that since these header fields are already defined in other specifications, it is not necessary to include them here again. Furthermore, the Content-Disposition
header field's format is not clearly enough defined. For example, it is left open which disposition value should be used in the header field. There needs to be more discussion whether this approach is suited or not.¶
However, from experience with the tus project, users are often asking for a way to communicate the file name and file type. Therefore, we believe it is help to explicitly include an approach for doing so.¶
-Are multipart requests supported? Yes, requests whose content is encoded using the multipart/form-data
are implicitly supported. The entire encoded content can be considered as a single file, which is then uploaded using the resumable protocol. The server, of course, must store the delimiter ("boundary") separating each part and must be able to parse the multipart format once the upload is completed.¶
This document is based on an Internet-Draft specification written by Jiten Mehta, Stefan Matsson, and the authors of this document.¶
-The tus v1 protocol is a specification for a resumable file upload protocol over HTTP. It inspired the early design of this protocol. Members of the tus community helped significantly in the process of bringing this work to the IETF.¶
-The authors would like to thank Mark Nottingham for substantive contributions to the text.¶
-This section is to be removed before publishing as an RFC.¶
-None¶
-Split the Upload Transfer Procedure into the Upload Creation Procedure and the Upload Appending Procedure.¶
-Internet-Draft | -Retrofit Structured Fields | -January 2024 | -
Nottingham | -Expires 27 July 2024 | -[Page] | -
This specification nominates a selection of existing HTTP fields whose values are compatible with Structured Fields syntax, so that they can be handled as such (subject to certain caveats).¶
-To accommodate some additional fields whose syntax is not compatible, it also defines mappings of their semantics into Structured Fields. It does not specify how to convey them in HTTP messages.¶
-This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-retrofit/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/retrofit.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-Structured Field Values for HTTP [STRUCTURED-FIELDS] introduced a data model with associated parsing and serialization algorithms for use by new HTTP field values. Fields that are defined as Structured Fields can bring advantages that include:¶
-Improved interoperability and security: precisely defined parsing and serialisation algorithms are typically not available for fields defined with just ABNF and/or prose.¶
-Reuse of common implementations: many parsers for other fields are specific to a single field or a small family of fields.¶
-Canonical form: because a deterministic serialisation algorithm is defined for each type, Structure Fields have a canonical representation.¶
-Enhanced API support: a regular data model makes it easier to expose field values as a native data structure in implementations.¶
-Alternative serialisations: While [STRUCTURED-FIELDS] defines a textual serialisation of that data model, other, more efficient serialisations of the underlying data model are also possible.¶
-However, a field needs to be defined as a Structured Field for these benefits to be realised. Many existing fields are not, making up the bulk of header and trailer fields seen in HTTP traffic on the internet.¶
-This specification defines how a selection of existing HTTP fields can be handled as Structured Fields, so that these benefits can be realised -- thereby making them Retrofit Structured Fields.¶
-It does so using two techniques. Section 2 lists compatible fields -- those that can be handled as if they were Structured Fields due to the similarity of their defined syntax to that in Structured Fields. Section 3 lists mapped fields -- those whose syntax needs to be transformed into an underlying data model which is then mapped into that defined by Structured Fields.¶
-Retrofitting data structures onto existing and widely-deployed HTTP fields requires careful handling to assure interoperability and security. This section highlights considerations for applications that use Retrofit Structured Fields.¶
-While the majority of field values seen in HTTP traffic should be able to be parsed or mapped successfully, some will not. An application using Retrofit Structured Fields will need to define how unsuccessful values will be handled.¶
-For example, an API that exposes field values using Structured Fields data types might make the field value available as a string in cases where the field did not successfully parse or map.¶
-The mapped field values described in Section 3 are not compatible with the original syntax of their fields, and so cannot be used unless parties processing them have explicitly indicated their support for that form of the field value. An application using Retrofit Structured Fields will need to define how to negotiate support for them.¶
-For example, an alternative serialization of fields that takes advantage of Structured Fields would need to establish an explicit negotiation mechanism to assure that both peers would handle that serialization appropriately before using it.¶
- -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", -"MAY", and "OPTIONAL" in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here.¶
-The HTTP fields listed in Table 1 have values that can be handled as Structured Field Values according to the parsing and serialisation algorithms in [STRUCTURED-FIELDS] corresponding to the listed top-level type, subject to the caveats in Section 2.1.¶
-The top-level types are chosen for compatibility with the defined syntax of the field as well as with actual internet traffic. However, not all instances of these fields will successfully parse as a Structured Field Value. This might be because the field value is clearly invalid, or it might be because it is valid but not parseable as a Structured Field.¶
-An application using this specification will need to consider how to handle such field values. Depending on its requirements, it might be advisable to reject such values, treat them as opaque strings, or attempt to recover a Structured Field Value from them in an ad hoc fashion.¶
-Field Name | -Structured Type | -
---|---|
Accept | -List | -
Accept-Encoding | -List | -
Accept-Language | -List | -
Accept-Patch | -List | -
Accept-Post | -List | -
Accept-Ranges | -List | -
Access-Control-Allow-Credentials | -Item | -
Access-Control-Allow-Headers | -List | -
Access-Control-Allow-Methods | -List | -
Access-Control-Allow-Origin | -Item | -
Access-Control-Expose-Headers | -List | -
Access-Control-Max-Age | -Item | -
Access-Control-Request-Headers | -List | -
Access-Control-Request-Method | -Item | -
Age | -Item | -
Allow | -List | -
ALPN | -List | -
Alt-Svc | -Dictionary | -
Alt-Used | -Item | -
Cache-Control | -Dictionary | -
CDN-Loop | -List | -
Clear-Site-Data | -List | -
Connection | -List | -
Content-Encoding | -List | -
Content-Language | -List | -
Content-Length | -List | -
Content-Type | -Item | -
Cross-Origin-Resource-Policy | -Item | -
DNT | -Item | -
Expect | -Dictionary | -
Expect-CT | -Dictionary | -
Host | -Item | -
Keep-Alive | -Dictionary | -
Max-Forwards | -Item | -
Origin | -Item | -
Pragma | -Dictionary | -
Prefer | -Dictionary | -
Preference-Applied | -Dictionary | -
Retry-After | -Item | -
Sec-WebSocket-Extensions | -List | -
Sec-WebSocket-Protocol | -List | -
Sec-WebSocket-Version | -Item | -
Server-Timing | -List | -
Surrogate-Control | -Dictionary | -
TE | -List | -
Timing-Allow-Origin | -List | -
Trailer | -List | -
Transfer-Encoding | -List | -
Upgrade-Insecure-Requests | -Item | -
Vary | -List | -
X-Content-Type-Options | -Item | -
X-Frame-Options | -Item | -
X-XSS-Protection | -List | -
Note the following caveats regarding compatibility:¶
-Some values may fail to parse as Structured Fields, even though they are valid according to their originally specified syntax. For example, HTTP parameter names are case-insensitive (per Section 5.6.6 of [HTTP]), but Structured Fields require them to be all-lowercase. -Likewise, many Dictionary-based fields (e.g., Cache-Control, Expect-CT, Pragma, Prefer, Preference-Applied, Surrogate-Control) have case-insensitive keys. -Similarly, the parameters rule in HTTP (see Section 5.6.6 of [HTTP]) allows whitespace before the ";" delimiter, but Structured Fields does not. -And, Section 5.6.4 of [HTTP] allows backslash-escaping most characters in quoted strings, whereas Structured Field Strings only escape "\" and DQUOTE. The vast majority of fields seen in typical traffic do not exhibit these behaviors.¶
-Parsing algorithms specified (or just widely implemented) for current HTTP headers may differ from those in Structured Fields in details such as error handling. For example, HTTP specifies that repeated directives in the Cache-Control header field have a different precedence than that assigned by a Dictionary structured field (which Cache-Control is mapped to).¶
-In Structured Fields, tokens are required to begin with an alphabetic character or "*", whereas HTTP tokens allow a wider range of characters. This prevents use of mapped values that begin with one of these characters. For example, media types, field names, methods, range-units, character and transfer codings that begin with a number or special character other than "*" might be valid HTTP protocol elements, but will not be able to be represented as Structured Field Tokens.¶
-Structured Fields Integers can have at most 15 digits; larger values will not be able to be represented in them.¶
-Fields whose values contain IPv6 literal addresses (such as CDN-Loop, Host, and Origin) are not able to be represented as Structured Fields Tokens, because the brackets used to delimit them are not allowed in Tokens.¶
-Empty and whitespace-only field values are considered errors in Structured Fields. For compatible fields, an empty field indicates that the field should be silently ignored.¶
-Some ALPN tokens (e.g., h3-Q43
) do not conform to key's syntax, and therefore cannot be represented as a Token. Since the final version of HTTP/3 uses the h3
token, this shouldn't be a long-term issue, although future tokens may again violate this assumption.¶
Note that Content-Length is defined as a List because it is not uncommon for implementations to mistakenly send multiple values. See Section 8.6 of [HTTP] for handling requirements.¶
-Only the delta-seconds form of Retry-After can be represented; a Retry-After value containing a http-date will need to be converted into delta-seconds to be conveyed as a Structured Field Value.¶
-Some HTTP field values have syntax that cannot be successfully parsed as Structured Field values. Instead, it is necessary to map them into a Structured Field value.¶
-For example, the Date HTTP header field carries a date:¶
- -Its value would be mapped to:¶
- -Unlike those listed in Section 2, these representations are not compatible with the original fields' syntax, and MUST NOT be used unless they are explicitly and unambiguously supported. For example, this means that sending them to a next-hop recipient in HTTP requires prior negotiation. This specification does not define how to do so.¶
-The field names in Table 2 have values that can be mapped into Structured Field values by treating the original field's value as a String.¶
-Field Name | -
---|
Content-Location | -
Location | -
Referer | -
For example, this Location field:¶
- -would have a mapped value of:¶
--"https://example.com/foo" -¶ -
The field names in Table 3 have values that can be mapped into Structured Field values by parsing their payload according to Section 5.6.7 of [HTTP] and representing the result as a Date.¶
-Field Name | -
---|
Date | -
Expires | -
If-Modified-Since | -
If-Unmodified-Since | -
Last-Modified | -
For example, an Expires field's value could be mapped as:¶
- -Please add the following note to the "Hypertext Transfer Protocol (HTTP) Field Name Registry":¶
-A prefix of "*" in the Structured Type column indicates that it is a retrofit type (i.e., not -natively Structured); see RFC nnnn.¶
-Then, add a new column, "Structured Type", with the values from Section 2 assigned to the nominated registrations, prefixing each with "*" to indicate that it is a retrofit type.¶
-Finally, add a new column to the "Cookie Attribute Registry" established by [COOKIES] with the title "Structured Type", using information from Table 4.¶
-Section 2 identifies existing HTTP fields that can be parsed and serialised with the algorithms defined in [STRUCTURED-FIELDS]. Variances from existing parser behavior might be exploitable, particularly if they allow an attacker to target one implementation in a chain (e.g., an intermediary). However, given the considerable variance in parsers already deployed, convergence towards a single parsing algorithm is likely to have a net security benefit in the longer term.¶
-Section 3 defines alternative representations of existing fields. Because downstream consumers might interpret the message differently based upon whether they recognise the alternative representation, implementations are prohibited from generating such values unless they have negotiated support for them with their peer. This specification does not define such a mechanism, but any such definition needs to consider the implications of doing so carefully.¶
-Internet-Draft | -Cookies: HTTP State Management Mechanism | -January 2024 | -
Bingler, et al. | -Expires 27 July 2024 | -[Page] | -
This document defines the HTTP Cookie and Set-Cookie header fields. These -header fields can be used by HTTP servers to store state (called cookies) at -HTTP user agents, letting the servers maintain a stateful session over the -mostly stateless HTTP protocol. Although cookies have many historical -infelicities that degrade their security and privacy, the Cookie and Set-Cookie -header fields are widely used on the Internet. This document obsoletes RFC -6265.¶
-This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-rfc6265bis/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/6265bis.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-- This document may contain material from IETF Documents or IETF - Contributions published or made publicly available before November - 10, 2008. The person(s) controlling the copyright in some of this - material may not have granted the IETF Trust the right to allow - modifications of such material outside the IETF Standards Process. - Without obtaining an adequate license from the person(s) - controlling the copyright in such materials, this document may not - be modified outside the IETF Standards Process, and derivative - works of it may not be created outside the IETF Standards Process, - except to format it for publication as an RFC or to translate it - into languages other than English.¶
-This document defines the HTTP Cookie and Set-Cookie header fields. Using -the Set-Cookie header field, an HTTP server can pass name/value pairs and -associated metadata (called cookies) to a user agent. When the user agent makes -subsequent requests to the server, the user agent uses the metadata and other -information to determine whether to return the name/value pairs in the Cookie -header field.¶
-Although simple on their surface, cookies have a number of complexities. For -example, the server indicates a scope for each cookie when sending it to the -user agent. The scope indicates the maximum amount of time in which the user -agent should return the cookie, the servers to which the user agent should -return the cookie, and the URI schemes for which the cookie is applicable.¶
-For historical reasons, cookies contain a number of security and privacy -infelicities. For example, a server can indicate that a given cookie is -intended for "secure" connections, but the Secure attribute does not provide -integrity in the presence of an active network attacker. Similarly, cookies -for a given host are shared across all the ports on that host, even though the -usual "same-origin policy" used by web browsers isolates content retrieved via -different ports.¶
-There are two audiences for this specification: developers of cookie-generating -servers and developers of cookie-consuming user agents.¶
-To maximize interoperability with user agents, servers SHOULD limit themselves -to the well-behaved profile defined in Section 4 when generating cookies.¶
-User agents MUST implement the more liberal processing rules defined in Section 5, in order to maximize interoperability with existing servers that do not -conform to the well-behaved profile defined in Section 4.¶
-This document specifies the syntax and semantics of these header fields as they are -actually used on the Internet. In particular, this document does not create -new syntax or semantics beyond those in use today. The recommendations for -cookie generation provided in Section 4 represent a preferred subset of current -server behavior, and even the more liberal cookie processing algorithm provided -in Section 5 does not recommend all of the syntactic and semantic variations in -use today. Where some existing software differs from the recommended protocol -in significant ways, the document contains a note explaining the difference.¶
- -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", -"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be -interpreted as described in [RFC2119].¶
-Requirements phrased in the imperative as part of algorithms (such as "strip any -leading space characters" or "return false and abort these steps") are to be -interpreted with the meaning of the key word ("MUST", "SHOULD", "MAY", etc.) -used in introducing the algorithm.¶
-Conformance requirements phrased as algorithms or specific steps can be -implemented in any manner, so long as the end result is equivalent. In -particular, the algorithms defined in this specification are intended to be -easy to understand and are not intended to be performant.¶
-This specification uses the Augmented Backus-Naur Form (ABNF) notation of -[RFC5234].¶
-The following core rules are included by reference, as defined in [RFC5234], -Appendix B.1: ALPHA (letters), CR (carriage return), CRLF (CR LF), CTLs -(controls), DIGIT (decimal 0-9), DQUOTE (double quote), HEXDIG -(hexadecimal 0-9/A-F/a-f), LF (line feed), NUL (null octet), OCTET (any -8-bit sequence of data except NUL), SP (space), HTAB (horizontal tab), -CHAR (any [USASCII] character), VCHAR (any visible [USASCII] character), -and WSP (whitespace).¶
-The OWS (optional whitespace) and BWS (bad whitespace) rules are defined in -Section 5.6.3 of [HTTPSEM].¶
-The terms "user agent", "client", "server", "proxy", and "origin server" have -the same meaning as in the HTTP/1.1 specification ([HTTPSEM], Section 3).¶
-The request-host is the name of the host, as known by the user agent, to which -the user agent is sending an HTTP request or from which it is receiving an HTTP -response (i.e., the name of the host to which it sent the corresponding HTTP -request).¶
-The term request-uri refers to "target URI" as defined in Section 7.1 of -[HTTPSEM].¶
-Two sequences of octets are said to case-insensitively match each other if and -only if they are equivalent under the i;ascii-casemap collation defined in -[RFC4790].¶
-The term string means a sequence of non-NUL octets.¶
-The terms "active browsing context", "active document", "ancestor navigables", -"container document", "content navigable", "dedicated worker", "Document", -"inclusive ancestor navigables", "navigable", "opaque origin", "sandboxed -origin browsing context flag", "shared worker", "the worker's Documents", -"top-level traversable", and "WorkerGlobalScope" are defined in [HTML].¶
-"Service Workers" are defined in the Service Workers specification -[SERVICE-WORKERS].¶
-The term "origin", the mechanism of deriving an origin from a URI, and the "the -same" matching algorithm for origins are defined in [RFC6454].¶
-"Safe" HTTP methods include GET
, HEAD
, OPTIONS
, and TRACE
, as defined
-in Section 9.2.1 of [HTTPSEM].¶
A domain's "public suffix" is the portion of a domain that is controlled by a
-public registry, such as "com", "co.uk", and "pvt.k12.wy.us". A domain's
-"registrable domain" is the domain's public suffix plus the label to its left.
-That is, for https://www.site.example
, the public suffix is example
, and the
-registrable domain is site.example
. Whenever possible, user agents SHOULD
-use an up-to-date public suffix list, such as the one maintained by the Mozilla
-project at [PSL].¶
The term "request", as well as a request's "client", "current url", "method", -"target browsing context", and "url list", are defined in [FETCH].¶
-The term "non-HTTP APIs" refers to non-HTTP mechanisms used to set and retrieve -cookies, such as a web browser API that exposes cookies to scripts.¶
-The term "top-level navigation" refers to a navigation of a top-level -traversable.¶
-This section outlines a way for an origin server to send state information to a -user agent and for the user agent to return the state information to the origin -server.¶
-To store state, the origin server includes a Set-Cookie header field in an HTTP -response. In subsequent requests, the user agent returns a Cookie request -header field to the origin server. The Cookie header field contains cookies the user agent -received in previous Set-Cookie header fields. The origin server is free to ignore -the Cookie header field or use its contents for an application-defined purpose.¶
-Origin servers MAY send a Set-Cookie response header field with any response. An -origin server can include multiple Set-Cookie header fields in a single response. -The presence of a Cookie or a Set-Cookie header field does not preclude HTTP -caches from storing and reusing a response.¶
-Origin servers SHOULD NOT fold multiple Set-Cookie header fields into a single -header field. The usual mechanism for folding HTTP headers fields (i.e., as -defined in Section 5.3 of [HTTPSEM]) might change the semantics of the Set-Cookie header -field because the %x2C (",") character is used by Set-Cookie in a way that -conflicts with such folding.¶
-User agents MAY ignore Set-Cookie header fields based on response status codes or -the user agent's cookie policy (see Section 5.3).¶
-Using the Set-Cookie header field, a server can send the user agent a short string -in an HTTP response that the user agent will return in future HTTP requests that -are within the scope of the cookie. For example, the server can send the user -agent a "session identifier" named SID with the value 31d4d96e407aad42. The -user agent then returns the session identifier in subsequent requests.¶
--== Server -> User Agent == - -Set-Cookie: SID=31d4d96e407aad42 - -== User Agent -> Server == - -Cookie: SID=31d4d96e407aad42 -¶ -
The server can alter the default scope of the cookie using the Path and -Domain attributes. For example, the server can instruct the user agent to -return the cookie to every path and every subdomain of site.example.¶
--== Server -> User Agent == - -Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=site.example - -== User Agent -> Server == - -Cookie: SID=31d4d96e407aad42 -¶ -
As shown in the next example, the server can store multiple cookies at the user -agent. For example, the server can store a session identifier as well as the -user's preferred language by returning two Set-Cookie header fields. Notice -that the server uses the Secure and HttpOnly attributes to provide -additional security protections for the more sensitive session identifier (see -Section 4.1.2).¶
--== Server -> User Agent == - -Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly -Set-Cookie: lang=en-US; Path=/; Domain=site.example - -== User Agent -> Server == - -Cookie: SID=31d4d96e407aad42; lang=en-US -¶ -
Notice that the Cookie header field above contains two cookies, one named SID and -one named lang. If the server wishes the user agent to persist the cookie over -multiple "sessions" (e.g., user agent restarts), the server can specify an -expiration date in the Expires attribute. Note that the user agent might -delete the cookie before the expiration date if the user agent's cookie store -exceeds its quota or if the user manually deletes the server's cookie.¶
--== Server -> User Agent == - -Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT - -== User Agent -> Server == - -Cookie: SID=31d4d96e407aad42; lang=en-US -¶ -
Finally, to remove a cookie, the server returns a Set-Cookie header field with an -expiration date in the past. The server will be successful in removing the -cookie only if the Path and the Domain attribute in the Set-Cookie header field -match the values used when the cookie was created.¶
--== Server -> User Agent == - -Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT - -== User Agent -> Server == - -Cookie: SID=31d4d96e407aad42 -¶ -
The upcoming two sections, Section 4 and Section 5, discuss -the set of requirements for two distinct types of implementations. This section -is meant to help guide implementers in determining which set of requirements -best fits their goals. Choosing the wrong set of requirements could result in a -lack of compatibility with other cookie implementations.¶
-It's important to note that being compatible means different things -depending on the implementer's goals. These differences have built up over time -due to both intentional and unintentional spec changes, spec interpretations, -and historical implementation differences.¶
-This section roughly divides implementers of the cookie spec into two types, -producers and consumers. These are not official terms and are only used here to -help readers develop an intuitive understanding of the use cases.¶
- - -This section describes the syntax and semantics of a well-behaved profile of the -Cookie and Set-Cookie header fields.¶
- - -This section specifies the Cookie and Set-Cookie header fields in sufficient -detail that a user agent implementing these requirements precisely can -interoperate with existing servers (even those that do not conform to the -well-behaved profile described in Section 4).¶
-A user agent could enforce more restrictions than those specified herein (e.g., -restrictions specified by its cookie policy, described in Section 7.2). -However, such additional restrictions may reduce the likelihood that a user -agent will be able to interoperate with existing servers.¶
-This section defines some algorithms used by user agents to process specific -subcomponents of the Cookie and Set-Cookie header fields.¶
- -A canonicalized host name is the string generated by the following algorithm:¶
-Convert the host name to a sequence of individual domain name labels.¶
-Convert each label that is not a Non-Reserved LDH (NR-LDH) label, to an -A-label (see Section 2.3.2.1 of [RFC5890] for the former and latter), or -to a "punycode label" (a label resulting from the "ToASCII" conversion in -Section 4 of [RFC3490]), as appropriate (see Section 6.3 of this -specification).¶
-Concatenate the resulting labels, separated by a %x2E (".") character.¶
-A string domain-matches a given domain string if at least one of the following -conditions hold:¶
- -Two origins are same-site if they satisfy the "same site" criteria defined in -[SAMESITE]. A request is "same-site" if the following criteria are true:¶
-The request is not the result of a cross-site redirect. That is, -the origin of every url in the request's url list is same-site with the -request's current url's origin.¶
-The request is not the result of a reload navigation triggered through a -user interface element (as defined by the user agent; e.g., a request -triggered by the user clicking a refresh button on a toolbar).¶
-The request's current url's origin is same-site with the request's -client's "site for cookies" (which is an origin), or if the request has no -client or the request's client is null.¶
-Requests which are the result of a reload navigation triggered through a user -interface element are same-site if the reloaded document was originally -navigated to via a same-site request. A request that is not "same-site" is -instead "cross-site".¶
-The request's client's "site for cookies" is calculated depending upon its -client's type, as described in the following subsections:¶
-The URI displayed in a user agent's address bar is the only security context -directly exposed to users, and therefore the only signal users can reasonably -rely upon to determine whether or not they trust a particular website. The -origin of that URI represents the context in which a user most likely believes -themselves to be interacting. We'll define this origin, the top-level -traversable's active document's origin, as the "top-level origin".¶
-For a document displayed in a top-level traversable, we can stop here: the -document's "site for cookies" is the top-level origin.¶
-For container documents, we need to audit the origins of each of a document's -ancestor navigables' active documents in order to account for the -"multiple-nested scenarios" described in Section 4 of [RFC7034]. A document's -"site for cookies" is the top-level origin if and only if the top-level origin -is same-site with the document's origin, and with each of the document's -ancestor documents' origins. Otherwise its "site for cookies" is an origin set -to an opaque origin.¶
-Given a Document (document
), the following algorithm returns its "site for
-cookies":¶
Let top-document
be the active document in document
's navigable's
-top-level traversable.¶
Let top-origin
be the origin of top-document
's URI if top-document
's
-sandboxed origin browsing context flag is set, and top-document
's origin
-otherwise.¶
Let documents
be a list consisting of the active documents of
-document
's inclusive ancestor navigables.¶
For each item
in documents
:¶
Return top-origin
.¶
Note: This algorithm only applies when the entire chain of documents from
-top-document
to document
are all active.¶
Worker-driven requests aren't as clear-cut as document-driven requests, as -there isn't a clear link between a top-level traversable and a worker. -This is especially true for Service Workers [SERVICE-WORKERS], which may -execute code in the background, without any document visible at all.¶
-Note: The descriptions below assume that workers must be same-origin with -the documents that instantiate them. If this invariant changes, we'll need to -take the worker's script's URI into account when determining their status.¶
- -Service Workers are more complicated, as they act as a completely separate -execution context with only tangential relationship to the Document which -registered them.¶
-How user agents handle Service Workers may differ, but user agents SHOULD -match the [SERVICE-WORKERS] specification.¶
-User agents' requirements for cookie name prefixes differ slightly from -servers' (Section 4.1.3) in that UAs MUST match the prefix string -case-insensitively.¶
-The normative requirements for the prefixes are detailed in the storage model -algorithm defined in Section 5.6.¶
-This is because some servers will process cookie case-insensitively, resulting -in them unintentionally miscapitalizing and accepting miscapitalized prefixes.¶
-For example, if a server sends the following Set-Cookie
header field¶
-Set-Cookie: __SECURE-SID=12345 -¶ -
to a UA which checks prefixes case-sensitively it will accept this cookie and
-the server would incorrectly believe the cookie is subject the same guarantees
-as one spelled __Secure-
.¶
Additionally the server is vulnerable to an attacker that purposefully
-miscapitalizes a cookie in order to impersonate a prefixed cookie. For example,
-a site already has a cookie __Secure-SID=12345
and by some means an attacker
-sends the following Set-Cookie
header field for the site to a UA which checks
-prefixes case-sensitively.¶
-Set-Cookie: __SeCuRe-SID=evil -¶ -
The next time a user visits the site the UA will send both cookies:¶
--Cookie: __Secure-SID=12345; __SeCuRe-SID=evil -¶ -
The server, being case-insensitive, won't be able to tell the difference -between the two cookies allowing the attacker to compromise the site.¶
-To prevent these issues, UAs MUST match cookie name prefixes case-insensitive.¶
-Note: Cookies with different names are still considered separate by UAs. So
-both __Secure-foo=bar
and __secure-foo=baz
can exist as distinct cookies
-simultaneously and both would have the requirements of the __Secure-
prefix
-applied.¶
The following are examples of Set-Cookie
header fields that would be rejected
-by a conformant user agent.¶
-Set-Cookie: __Secure-SID=12345; Domain=site.example -Set-Cookie: __secure-SID=12345; Domain=site.example -Set-Cookie: __SECURE-SID=12345; Domain=site.example -Set-Cookie: __Host-SID=12345 -Set-Cookie: __host-SID=12345; Secure -Set-Cookie: __host-SID=12345; Domain=site.example -Set-Cookie: __HOST-SID=12345; Domain=site.example; Path=/ -Set-Cookie: __Host-SID=12345; Secure; Domain=site.example; Path=/ -Set-Cookie: __host-SID=12345; Secure; Domain=site.example; Path=/ -Set-Cookie: __HOST-SID=12345; Secure; Domain=site.example; Path=/ -¶ -
Whereas the following Set-Cookie
header fields would be accepted if set from
-a secure origin.¶
-Set-Cookie: __Secure-SID=12345; Domain=site.example; Secure -Set-Cookie: __secure-SID=12345; Domain=site.example; Secure -Set-Cookie: __SECURE-SID=12345; Domain=site.example; Secure -Set-Cookie: __Host-SID=12345; Secure; Path=/ -Set-Cookie: __host-SID=12345; Secure; Path=/ -Set-Cookie: __HOST-SID=12345; Secure; Path=/ -¶ -
The user agent stores the following fields about each cookie: name, value, -expiry-time, domain, path, creation-time, last-access-time, -persistent-flag, host-only-flag, secure-only-flag, http-only-flag, -and same-site-flag.¶
-When the user agent "receives a cookie" from a request-uri with name -cookie-name, value cookie-value, and attributes cookie-attribute-list, the -user agent MUST process the cookie as follows:¶
-A user agent MAY ignore a received cookie in its entirety. See -Section 5.3.¶
-If cookie-name is empty and cookie-value is empty, abort these steps and -ignore the cookie entirely.¶
-If the cookie-name or the cookie-value contains a -%x00-08 / %x0A-1F / %x7F character (CTL characters excluding HTAB), -abort these steps and ignore the cookie entirely.¶
-If the sum of the lengths of cookie-name and cookie-value is more than -4096 octets, abort these steps and ignore the cookie entirely.¶
-Create a new cookie with name cookie-name, value cookie-value. Set the -creation-time and the last-access-time to the current date and time.¶
-If the cookie-attribute-list contains an attribute with an attribute-name -of "Max-Age":¶
-Set the cookie's persistent-flag to true.¶
-Set the cookie's expiry-time to attribute-value of the last -attribute in the cookie-attribute-list with an attribute-name of -"Max-Age".¶
--Otherwise, if the cookie-attribute-list contains an attribute with an -attribute-name of "Expires" (and does not contain an attribute with an -attribute-name of "Max-Age"):¶
-Set the cookie's persistent-flag to true.¶
-Set the cookie's expiry-time to attribute-value of the last -attribute in the cookie-attribute-list with an attribute-name of -"Expires".¶
--Otherwise:¶
- -If the cookie-attribute-list contains an attribute with an -attribute-name of "Domain":¶
-Let the domain-attribute be the attribute-value of the last -attribute in the cookie-attribute-list with both an -attribute-name of "Domain" and an attribute-value whose -length is no more than 1024 octets. (Note that a leading %x2E -("."), if present, is ignored even though that character is not -permitted.)¶
--Otherwise:¶
-Let the domain-attribute be the empty string.¶
-If the domain-attribute contains a character that is not in the range of [USASCII] -characters, abort these steps and ignore the cookie entirely.¶
-If the user agent is configured to reject "public suffixes" and the -domain-attribute is a public suffix:¶
-If the domain-attribute is identical to the canonicalized -request-host:¶
-Let the domain-attribute be the empty string.¶
--Otherwise:¶
-Abort these steps and ignore the cookie entirely.¶
-
-NOTE: This step prevents attacker.example
from disrupting the integrity of
-site.example
by setting a cookie with a Domain attribute of "example".¶
If the domain-attribute is non-empty:¶
-If the canonicalized request-host does not domain-match the -domain-attribute:¶
-Abort these steps and ignore the cookie entirely.¶
--Otherwise:¶
- --Otherwise:¶
- -If the cookie-attribute-list contains an attribute with an -attribute-name of "Path", set the cookie's path to attribute-value of -the last attribute in the cookie-attribute-list with both an -attribute-name of "Path" and an attribute-value whose length is no -more than 1024 octets. Otherwise, set the cookie's path to the -default-path of the request-uri.¶
-If the cookie-attribute-list contains an attribute with an -attribute-name of "Secure", set the cookie's secure-only-flag to true. -Otherwise, set the cookie's secure-only-flag to false.¶
-If the scheme component of the request-uri does not denote a "secure" - protocol (as defined by the user agent), and the cookie's secure-only-flag - is true, then abort these steps and ignore the cookie entirely.¶
-If the cookie-attribute-list contains an attribute with an -attribute-name of "HttpOnly", set the cookie's http-only-flag to true. -Otherwise, set the cookie's http-only-flag to false.¶
-If the cookie was received from a "non-HTTP" API and the cookie's -http-only-flag is true, abort these steps and ignore the cookie entirely.¶
-If the cookie's secure-only-flag is false, and the scheme component of -request-uri does not denote a "secure" protocol, then abort these steps and -ignore the cookie entirely if the cookie store contains one or more cookies -that meet all of the following criteria:¶
-Their name matches the name of the newly-created cookie.¶
-Their secure-only-flag is true.¶
-Their domain domain-matches the domain of the newly-created cookie, or -vice-versa.¶
-The path of the newly-created cookie path-matches the path of the -existing cookie.¶
--Note: The path comparison is not symmetric, ensuring only that a -newly-created, non-secure cookie does not overlay an existing secure -cookie, providing some mitigation against cookie-fixing attacks. That is, -given an existing secure cookie named 'a' with a path of '/login', a -non-secure cookie named 'a' could be set for a path of '/' or '/foo', but -not for a path of '/login' or '/login/en'.¶
-If the cookie-attribute-list contains an attribute with an -attribute-name of "SameSite", and an attribute-value of "Strict", "Lax", or -"None", set the cookie's same-site-flag to the attribute-value of the last -attribute in the cookie-attribute-list with an attribute-name of "SameSite". -Otherwise, set the cookie's same-site-flag to "Default".¶
-If the cookie's same-site-flag
is not "None":¶
If the cookie was received from a "non-HTTP" API, and the API was called -from a navigable's active document whose "site for cookies" is -not same-site with the top-level origin, then abort these steps and -ignore the newly created cookie entirely.¶
-If the cookie was received from a "same-site" request (as defined in -Section 5.2), skip the remaining substeps and continue -processing the cookie.¶
-If the cookie was received from a request which is navigating a
-top-level traversable [HTML] (e.g. if the request's "reserved
-client" is either null
or an environment whose "target browsing
-context"'s navigable is a top-level traversable), skip the remaining
-substeps and continue processing the cookie.¶
-Note: Top-level navigations can create a cookie with any SameSite
-value, even if the new cookie wouldn't have been sent along with
-the request had it already existed prior to the navigation.¶
Abort these steps and ignore the newly created cookie entirely.¶
-If the cookie's "same-site-flag" is "None", abort these steps and ignore the -cookie entirely unless the cookie's secure-only-flag is true.¶
-If the cookie-name begins with a case-insensitive match for the string -"__Secure-", abort these steps and ignore the cookie entirely unless the -cookie's secure-only-flag is true.¶
-If the cookie-name begins with a case-insensitive match for the string -"__Host-", abort these steps and ignore the cookie entirely unless the -cookie meets all the following criteria:¶
- -If the cookie-name is empty and either of the following conditions are -true, abort these steps and ignore the cookie:¶
- -If the cookie store contains a cookie with the same name, domain, -host-only-flag, and path as the newly-created cookie:¶
-Let old-cookie be the existing cookie with the same name, domain, -host-only-flag, and path as the newly-created cookie. (Notice that this -algorithm maintains the invariant that there is at most one such -cookie.)¶
-If the newly-created cookie was received from a "non-HTTP" API and the -old-cookie's http-only-flag is true, abort these steps and ignore the -newly created cookie entirely.¶
-Update the creation-time of the newly-created cookie to match the -creation-time of the old-cookie.¶
-Remove the old-cookie from the cookie store.¶
-Insert the newly-created cookie into the cookie store.¶
-A cookie is "expired" if the cookie has an expiry date in the past.¶
-The user agent MUST evict all expired cookies from the cookie store if, at any -time, an expired cookie exists in the cookie store.¶
-At any time, the user agent MAY "remove excess cookies" from the cookie store -if the number of cookies sharing a domain field exceeds some -implementation-defined upper bound (such as 50 cookies).¶
-At any time, the user agent MAY "remove excess cookies" from the cookie store -if the cookie store exceeds some predetermined upper bound (such as 3000 -cookies).¶
-When the user agent removes excess cookies from the cookie store, the user -agent MUST evict cookies in the following priority order:¶
-Expired cookies.¶
-Cookies whose secure-only-flag is false, and which share a domain field -with more than a predetermined number of other cookies.¶
-Cookies that share a domain field with more than a predetermined number of -other cookies.¶
-All cookies.¶
-If two cookies have the same removal priority, the user agent MUST evict the -cookie with the earliest last-access-time first.¶
-When "the current session is over" (as defined by the user agent), the user -agent MUST remove from the cookie store all cookies with the persistent-flag -set to false.¶
-This section defines how cookies are retrieved from a cookie store in the form -of a cookie-string. A "retrieval" is any event which requires generating a -cookie-string. For example, a retrieval may occur in order to build a Cookie -header field for an HTTP request, or may be required in order to return a -cookie-string from a call to a "non-HTTP" API that provides access to cookies. A -retrieval has an associated URI, same-site status, and type, which -are defined below depending on the type of retrieval.¶
- -The user agent MAY implement "non-HTTP" APIs that can be used to access -stored cookies.¶
-A user agent MAY return an empty cookie-string in certain contexts, such as -when a retrieval occurs within a third-party context (see -Section 7.1).¶
-If a user agent does return cookies for a given call to a "non-HTTP" API with -an associated Document, then the user agent MUST compute the cookie-string -following the algorithm defined in Section 5.7.3, where the -retrieval's URI is defined by the caller (see [DOM-DOCUMENT-COOKIE]), the -retrieval's same-site status is "same-site" if the Document's "site for -cookies" is same-site with the top-level origin as defined in -Section 5.2.1 (otherwise it is "cross-site"), and the retrieval's type -is "non-HTTP".¶
-Given a cookie store and a retrieval, the following algorithm returns a -cookie-string from a given cookie store.¶
-Let cookie-list be the set of cookies from the cookie store that meets all -of the following requirements:¶
-Either:¶
-The cookie's host-only-flag is true and the canonicalized -host of the retrieval's URI is identical to the cookie's domain.¶
--Or:¶
-The cookie's host-only-flag is false and the canonicalized -host of the retrieval's URI domain-matches the cookie's domain.¶
--NOTE: (For user agents configured to reject "public suffixes") It's -possible that the public suffix list was changed since a cookie was -created. If this change results in a cookie's domain becoming a public -suffix then that cookie is considered invalid as it would have been -rejected during creation (See Section 5.6 step 9). User agents -should be careful to avoid retrieving these invalid cookies even if they -domain-match the host of the retrieval's URI.¶
-The retrieval's URI's path path-matches the cookie's path.¶
-If the cookie's secure-only-flag is true, then the retrieval's URI's -scheme must denote a "secure" protocol (as defined by the user agent).¶
--NOTE: The notion of a "secure" protocol is not defined by this document. -Typically, user agents consider a protocol secure if the protocol makes -use of transport-layer security, such as SSL or TLS. For example, most -user agents consider "https" to be a scheme that denotes a secure -protocol.¶
-If the cookie's http-only-flag is true, then exclude the cookie if the -retrieval's type is "non-HTTP".¶
-If the cookie's same-site-flag is not "None" and the retrieval's same-site -status is "cross-site", then exclude the cookie unless all of the -following conditions are met:¶
-The retrieval's type is "HTTP".¶
-The same-site-flag is "Lax" or "Default".¶
-The HTTP request associated with the retrieval uses a "safe" method.¶
-The target browsing context of the HTTP request associated with the -retrieval is the active browsing context or a top-level traversable.¶
-The user agent SHOULD sort the cookie-list in the following order:¶
-Cookies with longer paths are listed before cookies with shorter -paths.¶
-Among cookies that have equal-length path fields, cookies with earlier -creation-times are listed before cookies with later creation-times.¶
--NOTE: Not all user agents sort the cookie-list in this order, but this order -reflects common practice when this document was written, and, historically, -there have been servers that (erroneously) depended on this order.¶
-Update the last-access-time of each cookie in the cookie-list to the -current date and time.¶
-Serialize the cookie-list into a cookie-string by processing each cookie -in the cookie-list in order:¶
- -Practical user agent implementations have limits on the number and size of -cookies that they can store. General-use user agents SHOULD provide each of the -following minimum capabilities:¶
- -User agents MAY limit the maximum number of cookies they store, and may evict -any cookie at any time (whether at the request of the user or due to -implementation limitations).¶
-Note that a limit on the maximum number of cookies also limits the total size of -the stored cookies, due to the length limits which MUST be enforced in -Section 5.5.¶
-Servers SHOULD use as few and as small cookies as possible to avoid reaching -these implementation limits and to minimize network bandwidth due to the -Cookie header field being included in every request.¶
-Servers SHOULD gracefully degrade if the user agent fails to return one or more -cookies in the Cookie header field because the user agent might evict any cookie -at any time.¶
-One reason the Cookie and Set-Cookie header fields use such esoteric syntax is -that many platforms (both in servers and user agents) provide a string-based -application programming interface (API) to cookies, requiring -application-layer programmers to generate and parse the syntax used by the -Cookie and Set-Cookie header fields, which many programmers have done incorrectly, -resulting in interoperability problems.¶
-Instead of providing string-based APIs to cookies, platforms would be -well-served by providing more semantic APIs. It is beyond the scope of this -document to recommend specific API designs, but there are clear benefits to -accepting an abstract "Date" object instead of a serialized date string.¶
-IDNA2008 [RFC5890] supersedes IDNA2003 [RFC3490]. However, there are -differences between the two specifications, and thus there can be differences -in processing (e.g., converting) domain name labels that have been registered -under one from those registered under the other. There will be a transition -period of some time during which IDNA2003-based domain name labels will exist -in the wild. User agents SHOULD implement IDNA2008 [RFC5890] and MAY -implement [UTS46] or [RFC5895] in order to facilitate their IDNA transition. -If a user agent does not implement IDNA2008, the user agent MUST implement -IDNA2003 [RFC3490].¶
-Cookies' primary privacy risk is their ability to correlate user activity. This -can happen on a single site, but is most problematic when activity is tracked across different, -seemingly unconnected Web sites to build a user profile.¶
-Over time, this capability (warned against explicitly in [RFC2109] and all of its successors) -has become widely used for varied reasons including:¶
-authenticating users across sites,¶
-assembling information on users,¶
-protecting against fraud and other forms of undesirable traffic,¶
-targeting advertisements at specific users or at users with specified attributes,¶
-measuring how often ads are shown to users, and¶
-recognizing when an ad resulted in a change in user behavior.¶
-While not every use of cookies is necessarily problematic for privacy, their potential for abuse -has become a widespread concern in the Internet community and broader society. In response to these concerns, user agents -have actively constrained cookie functionality in various ways (as allowed and encouraged by -previous specifications), while avoiding disruption to features they judge desirable for the health -of the Web.¶
-It is too early to declare consensus on which specific mechanism(s) should be used to mitigate cookies' privacy impact; user agents' ongoing changes to how they are handled are best characterised as experiments that -can provide input into that eventual consensus.¶
-Instead, this document describes limited, general mitigations against the privacy risks associated -with cookies that enjoy wide deployment at the time of writing. It is expected that implementations -will continue to experiment and impose stricter, more well-defined limitations on cookies over -time. Future versions of this document might codify those mechanisms based upon deployment -experience. If functions that currently rely on cookies can be supported by separate, targeted -mechanisms, they might be documented in separate specifications and stricter limitations on cookies -might become feasible.¶
-Note that cookies are not the only mechanism that can be used to track users across sites, so while -these mitigations are necessary to improve Web privacy, they are not sufficient on their own.¶
- - -User agents SHOULD provide users with a mechanism for managing the cookies -stored in the cookie store. For example, a user agent might let users delete -all cookies received during a specified time period or all the cookies related -to a particular domain. In addition, many user agents include a user interface -element that lets users examine the cookies stored in their cookie store.¶
-User agents SHOULD provide users with a mechanism for disabling cookies. When -cookies are disabled, the user agent MUST NOT include a Cookie header field in -outbound HTTP requests and the user agent MUST NOT process Set-Cookie header fields -in inbound HTTP responses.¶
-User agents MAY offer a way to change the cookie policy (see -Section 7.2).¶
-User agents MAY provide users the option of preventing persistent storage of -cookies across sessions. When configured thusly, user agents MUST treat all -received cookies as if the persistent-flag were set to false. Some popular -user agents expose this functionality via "private browsing" mode -[Aggarwal2010].¶
-Although servers can set the expiration date for cookies to the distant future, -most user agents do not actually retain cookies for multiple decades. Rather -than choosing gratuitously long expiration periods, servers SHOULD promote user -privacy by selecting reasonable cookie expiration periods based on the purpose -of the cookie. For example, a typical session identifier might reasonably be -set to expire in two weeks.¶
-Cookies have a number of security pitfalls. This section overviews a few of the -more salient issues.¶
-In particular, cookies encourage developers to rely on ambient authority for -authentication, often becoming vulnerable to attacks such as cross-site request -forgery [CSRF]. Also, when storing session identifiers in cookies, developers -often create session fixation vulnerabilities.¶
-Transport-layer encryption, such as that employed in HTTPS, is insufficient to -prevent a network attacker from obtaining or altering a victim's cookies because -the cookie protocol itself has various vulnerabilities (see "Weak Confidentiality" -and "Weak Integrity", below). In addition, by default, cookies do not provide -confidentiality or integrity from network attackers, even when used in conjunction -with HTTPS.¶
-Unless sent over a secure channel (such as TLS), the information in the Cookie -and Set-Cookie header fields is transmitted in the clear.¶
-All sensitive information conveyed in these header fields is exposed to an -eavesdropper.¶
-A malicious intermediary could alter the header fields as they travel in either -direction, with unpredictable results.¶
-A malicious client could alter the Cookie header fields before transmission, -with unpredictable results.¶
-Servers SHOULD encrypt and sign the contents of cookies (using whatever format -the server desires) when transmitting them to the user agent (even when sending -the cookies over a secure channel). However, encrypting and signing cookie -contents does not prevent an attacker from transplanting a cookie from one user -agent to another or from replaying the cookie at a later time.¶
-In addition to encrypting and signing the contents of every cookie, servers that -require a higher level of security SHOULD use the Cookie and Set-Cookie -header fields only over a secure channel. When using cookies over a secure channel, -servers SHOULD set the Secure attribute (see Section 4.1.2.5) for every -cookie. If a server does not set the Secure attribute, the protection -provided by the secure channel will be largely moot.¶
-For example, consider a webmail server that stores a session identifier in a -cookie and is typically accessed over HTTPS. If the server does not set the -Secure attribute on its cookies, an active network attacker can intercept any -outbound HTTP request from the user agent and redirect that request to the -webmail server over HTTP. Even if the webmail server is not listening for HTTP -connections, the user agent will still include cookies in the request. The -active network attacker can intercept these cookies, replay them against the -server, and learn the contents of the user's email. If, instead, the server had -set the Secure attribute on its cookies, the user agent would not have -included the cookies in the clear-text request.¶
-Instead of storing session information directly in a cookie (where it might be -exposed to or replayed by an attacker), servers commonly store a nonce (or -"session identifier") in a cookie. When the server receives an HTTP request -with a nonce, the server can look up state information associated with the -cookie using the nonce as a key.¶
-Using session identifier cookies limits the damage an attacker can cause if the -attacker learns the contents of a cookie because the nonce is useful only for -interacting with the server (unlike non-nonce cookie content, which might itself -be sensitive). Furthermore, using a single nonce prevents an attacker from -"splicing" together cookie content from two interactions with the server, which -could cause the server to behave unexpectedly.¶
-Using session identifiers is not without risk. For example, the server SHOULD -take care to avoid "session fixation" vulnerabilities. A session fixation attack -proceeds in three steps. First, the attacker transplants a session identifier -from his or her user agent to the victim's user agent. Second, the victim uses -that session identifier to interact with the server, possibly imbuing the -session identifier with the user's credentials or confidential information. -Third, the attacker uses the session identifier to interact with server -directly, possibly obtaining the user's authority or confidential information.¶
-Cookies do not provide isolation by port. If a cookie is readable by a service -running on one port, the cookie is also readable by a service running on another -port of the same server. If a cookie is writable by a service on one port, the -cookie is also writable by a service running on another port of the same server. -For this reason, servers SHOULD NOT both run mutually distrusting services on -different ports of the same host and use cookies to store security-sensitive -information.¶
-Cookies do not provide isolation by scheme. Although most commonly used with -the http and https schemes, the cookies for a given host might also be -available to other schemes, such as ftp and gopher. Although this lack of -isolation by scheme is most apparent in non-HTTP APIs that permit access to -cookies (e.g., HTML's document.cookie API), the lack of isolation by scheme -is actually present in requirements for processing cookies themselves (e.g., -consider retrieving a URI with the gopher scheme via HTTP).¶
-Cookies do not always provide isolation by path. Although the network-level -protocol does not send cookies stored for one path to another, some user -agents expose cookies via non-HTTP APIs, such as HTML's document.cookie API. -Because some of these user agents (e.g., web browsers) do not isolate resources -received from different paths, a resource retrieved from one path might be able -to access cookies stored for another path.¶
-Cookies do not provide integrity guarantees for sibling domains (and their -subdomains). For example, consider foo.site.example and bar.site.example. The -foo.site.example server can set a cookie with a Domain attribute of -"site.example" (possibly overwriting an existing "site.example" cookie set by -bar.site.example), and the user agent will include that cookie in HTTP requests -to bar.site.example. In the worst case, bar.site.example will be unable to -distinguish this cookie from a cookie it set itself. The foo.site.example -server might be able to leverage this ability to mount an attack against -bar.site.example.¶
-Even though the Set-Cookie header field supports the Path attribute, the Path -attribute does not provide any integrity protection because the user agent -will accept an arbitrary Path attribute in a Set-Cookie header field. For -example, an HTTP response to a request for http://site.example/foo/bar can set -a cookie with a Path attribute of "/qux". Consequently, servers SHOULD NOT -both run mutually distrusting services on different paths of the same host and -use cookies to store security-sensitive information.¶
-An active network attacker can also inject cookies into the Cookie header field -sent to https://site.example/ by impersonating a response from -http://site.example/ and injecting a Set-Cookie header field. The HTTPS server -at site.example will be unable to distinguish these cookies from cookies that -it set itself in an HTTPS response. An active network attacker might be able -to leverage this ability to mount an attack against site.example even if -site.example uses HTTPS exclusively.¶
-Servers can partially mitigate these attacks by encrypting and signing the
-contents of their cookies, or by naming the cookie with the __Secure-
prefix.
-However, using cryptography does not mitigate the issue completely because an
-attacker can replay a cookie he or she received from the authentic site.example
-server in the user's session, with unpredictable results.¶
Finally, an attacker might be able to force the user agent to delete cookies by -storing a large number of cookies. Once the user agent reaches its storage -limit, the user agent will be forced to evict some cookies. Servers SHOULD NOT -rely upon user agents retaining cookies.¶
-Cookies rely upon the Domain Name System (DNS) for security. If the DNS is -partially or fully compromised, the cookie protocol might fail to provide the -security properties required by applications.¶
-Fixes to formatting caused by mistakes in the initial port to Markdown:¶
- -Addresses errata 3444 by updating the path-value
and extension-av
-grammar, errata 4148 by updating the day-of-month
, year
, and time
-grammar, and errata 3663 by adding the requested note.
-https://www.rfc-editor.org/errata_search.php?rfc=6265¶
Dropped Cookie2
and Set-Cookie2
from the IANA Considerations section:
-https://github.com/httpwg/http-extensions/issues/247¶
Merged the recommendations from [I-D.ietf-httpbis-cookie-alone], removing -the ability for a non-secure origin to set cookies with a 'secure' flag, and -to overwrite cookies whose 'secure' flag is true.¶
-Merged the recommendations from [I-D.ietf-httpbis-cookie-prefixes], adding
-__Secure-
and __Host-
cookie name prefix processing instructions.¶
Merged the recommendations from [I-D.ietf-httpbis-cookie-same-site], adding
-support for the SameSite
attribute.¶
Closed a number of editorial bugs:¶
-Clarified address bar behavior for SameSite cookies: -https://github.com/httpwg/http-extensions/issues/201¶
-Added the word "Cookies" to the document's name: -https://github.com/httpwg/http-extensions/issues/204¶
-Clarified that the __Host-
prefix requires an explicit Path
attribute:
-https://github.com/httpwg/http-extensions/issues/222¶
Expanded the options for dealing with third-party cookies to include a -brief mention of partitioning based on first-party: -https://github.com/httpwg/http-extensions/issues/248¶
-Noted that double-quotes in cookie values are part of the value, and are -not stripped: https://github.com/httpwg/http-extensions/issues/295¶
-Fixed the "site for cookies" algorithm to return something that makes -sense: https://github.com/httpwg/http-extensions/issues/302¶
-Clarified handling of invalid SameSite values: -https://github.com/httpwg/http-extensions/issues/389¶
-Reflect widespread implementation practice of including a cookie's
-host-only-flag
when calculating its uniqueness:
-https://github.com/httpwg/http-extensions/issues/199¶
Introduced an explicit "None" value for the SameSite attribute: -https://github.com/httpwg/http-extensions/issues/788¶
-Allow SameSite
cookies to be set for all top-level navigations.
-https://github.com/httpwg/http-extensions/issues/594¶
Treat Set-Cookie: token
as creating the cookie ("", "token")
:
-https://github.com/httpwg/http-extensions/issues/159¶
Reject cookies with neither name nor value (e.g. Set-Cookie: =
and
-Set-Cookie:
: https://github.com/httpwg/http-extensions/issues/159¶
Clarified behavior of multiple SameSite
attributes in a cookie string:
-https://github.com/httpwg/http-extensions/issues/901¶
Editorial fixes: https://github.com/httpwg/http-extensions/issues/1059, -https://github.com/httpwg/http-extensions/issues/1158.¶
-Created a registry for cookie attribute names: -https://github.com/httpwg/http-extensions/pull/1060.¶
-Tweaks to ABNF for cookie-pair
and the Cookie
header
-production: https://github.com/httpwg/http-extensions/issues/1074,
-https://github.com/httpwg/http-extensions/issues/1119.¶
Fixed serialization for nameless/valueless cookies: -https://github.com/httpwg/http-extensions/pull/1143.¶
-Converted a normative reference to Mozilla's Public Suffix List [PSL] into -an informative reference: -https://github.com/httpwg/http-extensions/issues/1159.¶
-Moved instruction to ignore cookies with empty cookie-name and cookie-value -from Section 5.5 to Section 5.6 to ensure that they apply to cookies -created without parsing a cookie string: -https://github.com/httpwg/http-extensions/issues/1234.¶
-Add a default enforcement value to the same-site-flag
, equivalent to
-"SameSite=Lax":
-https://github.com/httpwg/http-extensions/pull/1325.¶
Require a Secure attribute for "SameSite=None": -https://github.com/httpwg/http-extensions/pull/1323.¶
-Consider scheme when running the same-site algorithm: - https://github.com/httpwg/http-extensions/pull/1324.¶
-Define "same-site" for reload navigation requests, e.g. those triggered via -user interface elements: -https://github.com/httpwg/http-extensions/pull/1384¶
-Consider redirects when defining same-site: -https://github.com/httpwg/http-extensions/pull/1348¶
-Align on using HTML terminology for origins: -https://github.com/httpwg/http-extensions/pull/1416¶
-Modify cookie parsing and creation algorithms in Section 5.5 and -Section 5.6 to explicitly handle control characters: -https://github.com/httpwg/http-extensions/pull/1420¶
-Refactor cookie retrieval algorithm to support non-HTTP APIs: -https://github.com/httpwg/http-extensions/pull/1428¶
-Define "Lax-allowing-unsafe" SameSite enforcement mode: -https://github.com/httpwg/http-extensions/pull/1435¶
-Consistently use "header field" (vs 'header"): -https://github.com/httpwg/http-extensions/pull/1527¶
-Update cookie size requirements: -https://github.com/httpwg/http-extensions/pull/1563¶
-Reject cookies with control characters: -https://github.com/httpwg/http-extensions/pull/1576¶
-No longer treat horizontal tab as a control character: -https://github.com/httpwg/http-extensions/pull/1589¶
-Specify empty domain attribute handling: -https://github.com/httpwg/http-extensions/pull/1709¶
-Standardize Max-Age/Expires upper bound: -https://github.com/httpwg/http-extensions/pull/1732, -https://github.com/httpwg/http-extensions/pull/1980.¶
-Expand on privacy considerations and third-party cookies: -https://github.com/httpwg/http-extensions/pull/1878¶
-Specify that no decoding of Set-Cookie line should occur: -https://github.com/httpwg/http-extensions/pull/1902¶
-Require ASCII for domain attributes: -https://github.com/httpwg/http-extensions/pull/1969¶
-Typos, formatting and editorial fixes: -https://github.com/httpwg/http-extensions/pull/1789, -https://github.com/httpwg/http-extensions/pull/1858, -https://github.com/httpwg/http-extensions/pull/2069.¶
-Remove note to ignore Domain attribute with trailing dot: -https://github.com/httpwg/http-extensions/pull/2087, -https://github.com/httpwg/http-extensions/pull/2092.¶
-Remove an inadvertant change to cookie-octet: -https://github.com/httpwg/http-extensions/pull/2090¶
-Remove note regarding cookie serialization: -https://github.com/httpwg/http-extensions/pull/2165¶
-Add case insensitivity note to Set-Cookie Syntax: -https://github.com/httpwg/http-extensions/pull/2167¶
-Add note not to send invalid cookies due to public suffix list changes: -https://github.com/httpwg/http-extensions/pull/2215¶
-Add warning to not send nameless cookies: -https://github.com/httpwg/http-extensions/pull/2220¶
-Add note regarding Service Worker's computation of "site for cookies": -https://github.com/httpwg/http-extensions/pull/2217¶
-Compare cookie name prefixes case-insensitively: -https://github.com/httpwg/http-extensions/pull/2236¶
-Update editors and the acknowledgements -https://github.com/httpwg/http-extensions/pull/2244¶
-Prevent nameless cookies with prefixed values -https://github.com/httpwg/http-extensions/pull/2251¶
-Advise the reader which section to implement -https://github.com/httpwg/http-extensions/pull/2478¶
-Define top-level navigation -https://github.com/httpwg/http-extensions/pull/2481¶
-Use navigables concept -https://github.com/httpwg/http-extensions/pull/2478¶
-RFC 6265 was written by Adam Barth. This document is an update of RFC 6265, -adding features and aligning the specification with the reality of today’s -deployments. Here, we’re standing upon the shoulders of a giant since the -majority of the text is still Adam’s.¶
-Thank you to both Lily Chen and Steven Englehardt, editors emeritus, for their -significant contributions improving this draft.¶
-Internet-Draft | -The HTTP QUERY Method | -January 2024 | -
Reschke, et al. | -Expires 27 July 2024 | -[Page] | -
- This specification defines a new HTTP method, QUERY, as a safe, idempotent - request method that can carry request content.¶
-This note is to be removed before publishing as an RFC.¶
-- Discussion of this draft takes place on the HTTP working group - mailing list (ietf-http-wg@w3.org), which is archived at - https://lists.w3.org/Archives/Public/ietf-http-wg/.¶
-- Working Group information can be found at https://httpwg.org/; - source code and issues list for this draft can be found at - https://github.com/httpwg/http-extensions/labels/safe-method-w-body.¶
-- The changes in this draft are summarized in Appendix A.3.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-- This specification defines the HTTP QUERY request method as a means of - making a safe, idempotent request that contains content.¶
-- Most often, this is desirable when the data conveyed in a request is - too voluminous to be encoded into the request's URI. For example, while - this is an common and interoperable query:¶
- -- if the query parameters extend to several kilobytes or more of - data it may not be, because many implementations place limits on their size. Often these limits are not - known or discoverable ahead of time, because a request can pass through many uncoordinated - systems. Additionally, expressing some data in the target URI is inefficient, because it - needs to be encoded to be a valid URI.¶
-- Encoding query parameters directly into the request URI also effectively - casts every possible combination of query inputs as distinct - resources. Depending on the application, that may not be desirable.¶
-- As an alternative to using GET, many implementations make use of the - HTTP POST method to perform queries, as illustrated in the example - below. In this case, the input parameters to the search operation are - passed along within the request content as opposed to using the - request URI.¶
-- A typical use of HTTP POST for requesting a search¶
- -- This variation, however, suffers from the same basic limitation as GET - in that it is not readily apparent -- absent specific knowledge of the - resource and server to which the request is being sent -- that a safe, - idempotent query is being performed.¶
-- The QUERY method provides a solution that spans the gap between the use of GET and POST. As - with POST, the input to the query operation is passed along within the content of the request - rather than as part of the request URI. Unlike POST, however, the method is explicitly safe - and idempotent, allowing functions like caching and automatic retries to operate.¶
-- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL - NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", - "MAY", and "OPTIONAL" in this document are to be interpreted as - described in BCP 14 [RFC2119] [RFC8174] when, and only when, they - appear in all capitals, as shown here.¶
-- The QUERY method is used to initiate a server-side query. Unlike - the HTTP GET method, which requests that a server return a - representation of the resource identified by the target URI - (as defined by Section 7.1 of [HTTP]), the QUERY - method is used to ask the server to perform a query operation - (described by the request content) over some set of data scoped to the - effective request URI. The content returned in response to a QUERY - cannot be assumed to be a representation of the resource identified by - the effective request URI.¶
-- The content of the request defines the query. Implementations MAY use - a request content of any media type with the QUERY method, provided that it - has appropriate query semantics.¶
-- QUERY requests are both safe and idempotent with regards to the - resource identified by the request URI. That is, QUERY requests do not - alter the state of the targeted resource. However, while processing a - QUERY request, a server can be expected to allocate computing and memory - resources or even create additional HTTP resources through which the - response can be retrieved.¶
-- A successful response to a QUERY request is expected to provide some - indication as to the final disposition of the operation. For - instance, a successful query that yields no results can be represented - by a 204 No Content response. If the response includes content, - it is expected to describe the results of the operation. - In some cases, the server may choose to respond indirectly to the QUERY - request by returning a 3xx Redirection with a Location header field specifying - an alternate Request URI from which the results can be retrieved - using an HTTP GET request. Various non-normative examples of successful - QUERY responses are illustrated in Section 4.¶
-- The semantics of the QUERY method change to a "conditional QUERY" if - the request message includes an If-Modified-Since, If-Unmodified- - Since, If-Match, If-None-Match, or If-Range header field - ([HTTP], Section 13). A conditional QUERY requests that the query - be performed only under the circumstances described by the conditional - header field(s). It is important to note, however, that such conditions - are evaluated against the state of the target resource itself as opposed - to the collected results of the search operation.¶
-- The response to a QUERY method is cacheable; a cache MAY use it to satisfy subsequent - QUERY requests as per Section 4 of [HTTP-CACHING]).¶
-- The cache key for a query (see Section 2 of [HTTP-CACHING]) MUST - incorporate the request content. When doing so, caches SHOULD first normalize request - content to remove semantically insignificant differences, thereby improving cache - efficiency, by:¶
-- Note that any such normalization is performed solely for the purpose of generating a cache key; it - does not change the request itself.¶
-- The "Accept-Query" response header field MAY be used by a resource to - directly signal support for the QUERY method while identifying - the specific query format media type(s) that may be used.¶
--Accept-Query = 1#media-type -¶ -
- The Accept-Query header field specifies a comma-separated listing of media - types (with optional parameters) as defined by - Section 8.3.1 of [HTTP].¶
-- The order of types listed by the Accept-Query header field is not significant.¶
-- Accept-Query's value applies to every URI on the server that shares the same path; in - other words, the query component is ignored. If requests to the same resource return - different Accept-Query values, the most recently received fresh (per - Section 4.2 of [HTTP-CACHING]) value is used.¶
-- The non-normative examples in this section make use of a simple, - hypothetical plain-text based query syntax based on SQL with results - returned as comma-separated values. This is done for illustration - purposes only. Implementations are free to use any format they wish on - both the request and response.¶
-A simple query with a direct response:¶
- -Response:¶
- -A simple query with an Indirect Response (303 See Other):¶
- -Response:¶
- -Fetch Query Response:¶
- -Response:¶
- -- The QUERY method is subject to the same general security - considerations as all HTTP methods as described in - [HTTP].¶
-- IANA is requested to add QUERY method in the - permanent registry at <http://www.iana.org/assignments/http-methods> - (see Section 16.1.1 of [HTTP]).¶
-Method Name | -Safe | -Idempotent | -Specification | -
---|---|---|---|
QUERY | -Yes | -Yes | -- Section 2 - | -
This section is to be removed before publishing as an RFC.¶
-Internet-Draft | -Structured Field Values for HTTP | -January 2024 | -
Nottingham & Kamp | -Expires 27 July 2024 | -[Page] | -
This document describes a set of data types and associated algorithms that are intended to make it easier and safer to define and handle HTTP header and trailer fields, known as "Structured Fields", "Structured Headers", or "Structured Trailers". It is intended for use by specifications of new HTTP fields that wish to use a common syntax that is more restrictive than traditional HTTP field values.¶
-This document obsoletes RFC 8941.¶
-This note is to be removed before publishing as an RFC.¶
-- Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-sfbis/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/header-structure.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-Specifying the syntax of new HTTP header (and trailer) fields is an onerous task; even with the guidance in Section 16.3.2 of [HTTP], there are many decisions -- and pitfalls -- for a prospective HTTP field author.¶
-Once a field is defined, bespoke parsers and serializers often need to be written, because each field value has a slightly different handling of what looks like common syntax.¶
-This document introduces a set of common data structures for use in definitions of new HTTP field values to address these problems. In particular, it defines a generic, abstract model for them, along with a concrete serialization for expressing that model in HTTP [HTTP] header and trailer fields.¶
-An HTTP field that is defined as a "Structured Header" or "Structured Trailer" (if the field can be either, it is a "Structured Field") uses the types defined in this specification to define its syntax and basic handling rules, thereby simplifying both its definition by specification writers and handling by implementations.¶
-Additionally, future versions of HTTP can define alternative serializations of the abstract model of these structures, allowing fields that use that model to be transmitted more efficiently without being redefined.¶
-Note that it is not a goal of this document to redefine the syntax of existing HTTP fields; the mechanisms described herein are only intended to be used with fields that explicitly opt into them.¶
-Section 2 describes how to specify a Structured Field.¶
-Section 3 defines a number of abstract data types that can be used in Structured Fields.¶
-Those abstract types can be serialized into and parsed from HTTP field values using the algorithms described in Section 4.¶
-This specification intentionally defines strict parsing and serialization behaviors using step-by-step algorithms; the only error handling defined is to fail the entire operation altogether.¶
-It is designed to encourage faithful implementation and good interoperability. Therefore, an implementation that tried to be helpful by being more tolerant of input would make interoperability worse, since that would create pressure on other implementations to implement similar (but likely subtly different) workarounds.¶
-In other words, strict processing is an intentional feature of this specification; it allows non-conformant input to be discovered and corrected by the producer early and avoids both interoperability and security issues that might otherwise result.¶
-Note that as a result of this strictness, if a field is appended to by multiple parties (e.g., intermediaries or different components in the sender), an error in one party's value is likely to cause the entire field value to fail parsing.¶
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
-This document uses the VCHAR, SP, DIGIT, ALPHA, and DQUOTE rules from [RFC5234] to specify characters and/or their corresponding ASCII bytes, depending on context. It uses the tchar and OWS rules from [HTTP] for the same purpose.¶
-This document uses algorithms to specify parsing and serialization behaviors. When parsing from HTTP fields, implementations MUST have behavior that is indistinguishable from following the algorithms.¶
-For serialization to HTTP fields, the algorithms define the recommended way to produce them. Implementations MAY vary from the specified behavior so long as the output is still correctly handled by the parsing algorithm described in Section 4.2.¶
-To specify an HTTP field as a Structured Field, its authors need to:¶
-Normatively reference this specification. Recipients and generators of the field need to know that the requirements of this document are in effect.¶
-Identify whether the field is a Structured Header (i.e., it can only be used in the header section -- the common case), a Structured Trailer (only in the trailer section), or a Structured Field (both).¶
-Specify the type of the field value; either List (Section 3.1), Dictionary (Section 3.2), or Item (Section 3.3).¶
-Define the semantics of the field value.¶
-Specify any additional constraints upon the field value, as well as the consequences when those constraints are violated.¶
-Typically, this means that a field definition will specify the top-level type -- List, Dictionary, or Item -- and then define its allowable types and constraints upon them. For example, a header defined as a List might have all Integer members, or a mix of types; a header defined as an Item might allow only Strings, and additionally only strings beginning with the letter "Q", or strings in lowercase. Likewise, Inner Lists (Section 3.1.1) are only valid when a field definition explicitly allows them.¶
-Field definitions can only use this specification for the entire field value, not a portion thereof.¶
-Specifications can refer to a field name as a "structured header name", "structured trailer name", or "structured field name" as appropriate. Likewise, they can refer its field value as a "structured header value", "structured trailer value", or "structured field value" as necessary.¶
-This specification defines minimums for the length or number of various structures supported by implementations. It does not specify maximum sizes in most cases, but authors should be aware that HTTP implementations do impose various limits on the size of individual fields, the total number of fields, and/or the size of the entire header or trailer section.¶
-A fictitious Foo-Example header field might be specified as:¶
---42. Foo-Example Header Field¶
-The Foo-Example HTTP header field conveys information about how -much Foo the message has.¶
-Foo-Example is an Item Structured Header Field [RFCnnnn]. Its value -MUST be an Integer (Section 3.3.1 of [RFCnnnn]).¶
-Its value indicates the amount of Foo in the message, and it MUST -be between 0 and 10, inclusive; other values MUST cause -the entire header field to be ignored.¶
-The following parameter is defined:¶
--
-- A parameter whose key is "foourl", and whose value is a String - (Section 3.3.3 of [RFCnnnn]), conveying the Foo URL - for the message. See below for processing requirements.¶ -
-"foourl" contains a URI-reference (Section 4.1 of [RFC3986]). If -its value is not a valid URI-reference, the entire header field -MUST be ignored. If its value is a relative reference (Section 4.2 -of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before -being used.¶
-For example:¶
---- Foo-Example: 2; foourl="https://foo.example.com/" -¶ -
When parsing fails, the entire field is ignored (see Section 4.2). Field definitions cannot override this, because doing so would preclude handling by generic software; they can only add additional constraints (for example, on the numeric range of Integers and Decimals, the format of Strings and Tokens, the types allowed in a Dictionary's values, or the number of Items in a List).¶
-When field-specific constraints are violated, the entire field is also ignored, unless the field definition defines other handling requirements. For example, if a header field is defined as an Item and required to be an Integer, but a String is received, it should be ignored unless that field's definition explicitly specifies otherwise.¶
-Structured Fields are designed to be extensible, because experience has shown that even when it is not foreseen, it is often necessary to modify and add to the allowable syntax and semantics of a field in a controlled fashion.¶
-Both Items and Inner Lists allow Parameters as an extensibility mechanism; this means that their values can later be extended to accommodate more information, if need be. To preserve forward compatibility, field specifications are discouraged from defining the presence of an unrecognized parameter as an error condition.¶
-Field specifications are required to be either an Item, List, or Dictionary to preserve extensibility. Fields that erroneously defined as another type (e.g., Integer) are assumed to be Items (i.e., they allow Parameters).¶
-To further assure that this extensibility is available in the future, and to encourage consumers to use a complete parser implementation, a field definition can specify that "grease" parameters be added by senders. A specification could stipulate that all parameters that fit a defined pattern are reserved for this use and then encourage them to be sent on some portion of requests. This helps to discourage recipients from writing a parser that does not account for Parameters.¶
-Specifications that use Dictionaries can also allow for forward compatibility by requiring that the presence of -- as well as value and type associated with -- unknown keys be ignored. Subsequent specifications can then add additional keys, specifying constraints on them as appropriate.¶
-An extension to a Structured Field can then require that an entire field value be ignored by a recipient that understands the extension if constraints on the value it defines are not met.¶
-Because a field definition needs to reference a specific RFC for Structured Fields, the types available for use in its value are limited to those defined in that RFC. For example, a field whose definition references this document can have a value that uses the Date type (Section 3.3.7), whereas a field whose definition references RFC 8941 cannot, because it will be treated as invalid (and therefore discarded) by implementations of that specification.¶
-This limitation also applies to future extensions to a field; for example, a field that is defined with reference to RFC 8941 cannot use the Date type, because some recipients might still be using an RFC 8941 parser to process it.¶
-However, this document is designed to be backwards-compatible with RFC 8941; a parser that implements the requirements here can also parse valid Structured Fields whose definitions reference RFC 8941.¶
-Upgrading a Structured Fields implementation to support a newer revision of the specification (such as this document) brings the possibility that some field values that were invalid according to the earlier RFC might become valid when processed.¶
-For example, field instance might contain a syntactically valid Date (Section 3.3.7), even though that field's definition does not accommodate Dates. An RFC8941 implementation would fail parsing such a field instance, because they are not defined in that specification. If that implementation were upgraded to this specification, parsing would now succeed. In some cases, the resulting Date value will be rejected by field-specific logic, but values in fields that are otherwise ignored (such as extension parameters) might not be detected and the field might subsequently be accepted and processed.¶
-This section defines the abstract types for Structured Fields, and summarizes how those types are serialized into textual HTTP fields.¶
-In summary:¶
-There are three top-level types that an HTTP field can be defined as: Lists, Dictionaries, and Items.¶
-Lists and Dictionaries are containers; their members can be Items or Inner Lists (which are themselves arrays of Items).¶
-Both Items and Inner Lists can be Parameterized with key/value pairs.¶
-Lists are arrays of zero or more members, each of which can be an Item (Section 3.3) or an Inner List (Section 3.1.1), both of which can be Parameterized (Section 3.1.2).¶
-An empty List is denoted by not serializing the field at all. This implies that fields defined as Lists have a default empty value.¶
-When serialized as a textual HTTP field, each member is separated by a comma and optional whitespace. For example, a field whose value is defined as a List of Tokens could look like:¶
- -Note that Lists can have their members split across multiple lines of the same header or trailer section, as per Section 5.3 of [HTTP]; for example, the following are equivalent:¶
- -and¶
- -However, individual members of a List cannot be safely split between lines; see Section 4.2 for details.¶
-Parsers MUST support Lists containing at least 1024 members. Field specifications can constrain the types and cardinality of individual List values as they require.¶
-An Inner List is an array of zero or more Items (Section 3.3). Both the individual Items and the Inner List itself can be Parameterized (Section 3.1.2).¶
-When serialized in a textual HTTP field, Inner Lists are denoted by surrounding parenthesis, and their values are delimited by one or more spaces. A field whose value is defined as a List of Inner Lists of Strings could look like:¶
- -Note that the last member in this example is an empty Inner List.¶
-A header field whose value is defined as a List of Inner Lists with Parameters at both levels could look like:¶
- -Parsers MUST support Inner Lists containing at least 256 members. Field specifications can constrain the types and cardinality of individual Inner List members as they require.¶
-Parameters are an ordered map of key-value pairs that are associated with an Item (Section 3.3) or Inner List (Section 3.1.1). The keys are unique within the scope of the Parameters they occur within, and the values are bare items (i.e., they themselves cannot be parameterized; see Section 3.3).¶
-Implementations MUST provide access to Parameters both by index and by key. Specifications MAY use either means of accessing them.¶
-Note that parameters are ordered, and parameter keys cannot contain uppercase letters.¶
-When serialized in a textual HTTP field, a Parameter is separated from its Item or Inner List and other Parameters by a semicolon. For example:¶
- -Parameters whose value is Boolean (see Section 3.3.6) true MUST omit that value when serialized. For example, the "a" parameter here is true, while the "b" parameter is false:¶
- -Note that this requirement is only on serialization; parsers are still required to correctly handle the true value when it appears in a parameter.¶
-Parsers MUST support at least 256 parameters on an Item or Inner List, and support parameter keys with at least 64 characters. Field specifications can constrain the order of individual parameters, as well as their values' types as required.¶
-Dictionaries are ordered maps of key-value pairs, where the keys are short textual strings and the values are Items (Section 3.3) or arrays of Items, both of which can be Parameterized (Section 3.1.2). There can be zero or more members, and their keys are unique in the scope of the Dictionary they occur within.¶
-Implementations MUST provide access to Dictionaries both by index and by key. Specifications MAY use either means of accessing the members.¶
-As with Lists, an empty Dictionary is represented by omitting the entire field. This implies that fields defined as Dictionaries have a default empty value.¶
-Typically, a field specification will define the semantics of Dictionaries by specifying the allowed type(s) for individual members by their keys, as well as whether their presence is required or optional. Recipients MUST ignore members whose keys are undefined or unknown, unless the field's specification specifically disallows them.¶
-When serialized as a textual HTTP field, Members are ordered as serialized and separated by a comma with optional whitespace. Member keys cannot contain uppercase characters. Keys and values are separated by "=" (without whitespace). For example:¶
- -Note that in this example, the final "=" is due to the inclusion of a Byte Sequence; see Section 3.3.5.¶
-Members whose value is Boolean (see Section 3.3.6) true MUST omit that value when serialized. For example, here both "b" and "c" are true:¶
- -Note that this requirement is only on serialization; parsers are still required to correctly handle the true Boolean value when it appears in Dictionary values.¶
-A Dictionary with a member whose value is an Inner List of Tokens:¶
- -A Dictionary with a mix of Items and Inner Lists, some with parameters:¶
- -Note that Dictionaries can have their members split across multiple lines of the same header or trailer section; for example, the following are equivalent:¶
- -and¶
- -However, individual members of a Dictionary cannot be safely split between lines; see Section 4.2 for details.¶
-Parsers MUST support Dictionaries containing at least 1024 key/value pairs and keys with at least 64 characters. Field specifications can constrain the order of individual Dictionary members, as well as their values' types as required.¶
-An Item can be an Integer (Section 3.3.1), a Decimal (Section 3.3.2), a String (Section 3.3.3), a Token (Section 3.3.4), a Byte Sequence (Section 3.3.5), a Boolean (Section 3.3.6), or a Date (Section 3.3.7). It can have associated parameters (Section 3.1.2).¶
-For example, a header field that is defined to be an Item that is an Integer might look like:¶
- -or with parameters:¶
- -Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 inclusive (i.e., up to fifteen digits, signed), for IEEE 754 compatibility [IEEE754].¶
-For example:¶
- -Integers larger than 15 digits can be supported in a variety of ways; for example, by using a String (Section 3.3.3), a Byte Sequence (Section 3.3.5), or a parameter on an Integer that acts as a scaling factor.¶
-While it is possible to serialize Integers with leading zeros (e.g., "0002", "-01") and signed zero ("-0"), these distinctions may not be preserved by implementations.¶
-Note that commas in Integers are used in this section's prose only for readability; they are not valid in the wire format.¶
-Decimals are numbers with an integer and a fractional component. The integer component has at most 12 digits; the fractional component has at most three digits.¶
-For example, a header whose value is defined as a Decimal could look like:¶
- -While it is possible to serialize Decimals with leading zeros (e.g., "0002.5", "-01.334"), trailing zeros (e.g., "5.230", "-0.40"), and signed zero (e.g., "-0.0"), these distinctions may not be preserved by implementations.¶
-Note that the serialization algorithm (Section 4.1.5) rounds input with more than three digits of precision in the fractional component. If an alternative rounding strategy is desired, this should be specified by the field definition to occur before serialization.¶
-Strings are zero or more printable ASCII [RFC0020] characters (i.e., the range %x20 to %x7E). Note that this excludes tabs, newlines, carriage returns, etc.¶
-Non-ASCII characters are not directly supported in Strings, because they cause a number of interoperability issues, and -- with few exceptions -- field values do not require them.¶
-When it is necessary for a field value to convey non-ASCII content, a Display String (Section 3.3.8) can be specified.¶
-When serialized in a textual HTTP field, Strings are delimited with double quotes, using a backslash ("\") to escape double quotes and backslashes. For example:¶
- -Note that Strings only use DQUOTE as a delimiter; single quotes do not delimit Strings. Furthermore, only DQUOTE and "\" can be escaped; other characters after "\" MUST cause parsing to fail.¶
-Parsers MUST support Strings (after any decoding) with at least 1024 characters.¶
-Tokens are short textual words that begin with an alphabetic character or "*", followed by zero to many token characters, which are the same as those allowed by the "token" ABNF rule defined in [HTTP], plus the ":" and "/" characters.¶
-For example:¶
- -Parsers MUST support Tokens with at least 512 characters.¶
-Note that Tokens are defined largely for compatibility with the data model of existing HTTP fields, and may require additional steps to use in some implementations. As a result, new fields are encouraged to use Strings.¶
-Byte Sequences can be conveyed in Structured Fields.¶
-When serialized in a textual HTTP field, a Byte Sequence is delimited with colons and encoded using base64 ([RFC4648], Section 4). For example:¶
- -Parsers MUST support Byte Sequences with at least 16384 octets after decoding.¶
-Boolean values can be conveyed in Structured Fields.¶
-When serialized in a textual HTTP field, a Boolean is indicated with a leading "?" character followed by a "1" for a true value or "0" for false. For example:¶
- -Note that in Dictionary (Section 3.2) and Parameter (Section 3.1.2) values, Boolean true is indicated by omitting the value.¶
-Date values can be conveyed in Structured Fields.¶
-Dates have a data model that is similar to Integers, representing a (possibly negative) delta in seconds from 1970-01-01T00:00:00Z, excluding leap seconds.¶
-For example:¶
- -Parsers MUST support Dates whose values include all days in years 1 to 9999 (i.e., -62,135,596,800 to 253,402,214,400 delta seconds from 1970-01-01T00:00:00Z).¶
-Display Strings are similar to Strings, in that they consist of zero or more characters, but they allow Unicode content, unlike Strings.¶
-Display Strings are intended for use in cases where a value is displayed to end users, and therefore may need to carry non-ASCII content. It is NOT RECOMMENDED that they be used in situations where a String (Section 3.3.3) or Token (Section 3.3.4) would be adequate, because Unicode has processing considerations (e.g., normalization) and security considerations (e.g., homograph attacks) that make it more difficult to handle correctly.¶
-Note that Display Strings do not indicate the language used in the value; that can be done separately if necessary (e.g., with a parameter).¶
-For example:¶
- -See Section 6 for additional security considerations when handling Display Strings.¶
-This section defines how to serialize and parse Structured Fields in textual HTTP field values and other encodings compatible with them (e.g., in HTTP/2 [HTTP/2] before compression with HPACK [HPACK]).¶
-Given a structure defined in this specification, return an ASCII string suitable for use in an HTTP field value.¶
-If the structure is a Dictionary or List and its value is empty (i.e., it has no members), do not serialize the field at all (i.e., omit both the field-name and field-value).¶
-If the structure is a List, let output_string be the result of running Serializing a List (Section 4.1.1) with the structure.¶
-Else, if the structure is a Dictionary, let output_string be the result of running Serializing a Dictionary (Section 4.1.2) with the structure.¶
-Else, if the structure is an Item, let output_string be the result of running Serializing an Item (Section 4.1.3) with the structure.¶
-Else, fail serialization.¶
-Return output_string converted into an array of bytes, using ASCII encoding [RFC0020].¶
-Given an array of (member_value, parameters) tuples as input_list, return an ASCII string suitable for use in an HTTP field value.¶
-Let output be an empty string.¶
-For each (member_value, parameters) of input_list:¶
-If member_value is an array, append the result of running Serializing an Inner List (Section 4.1.1.1) with (member_value, parameters) to output.¶
-Otherwise, append the result of running Serializing an Item (Section 4.1.3) with (member_value, parameters) to output.¶
-If more member_values remain in input_list:¶
- -Return output.¶
-Given an array of (member_value, parameters) tuples as inner_list, and parameters as list_parameters, return an ASCII string suitable for use in an HTTP field value.¶
-Let output be the string "(".¶
-For each (member_value, parameters) of inner_list:¶
-Append the result of running Serializing an Item (Section 4.1.3) with (member_value, parameters) to output.¶
-If more values remain in inner_list, append a single SP to output.¶
-Append ")" to output.¶
-Append the result of running Serializing Parameters (Section 4.1.1.2) with list_parameters to output.¶
-Return output.¶
-Given an ordered Dictionary as input_parameters (each member having a param_key and a param_value), return an ASCII string suitable for use in an HTTP field value.¶
-Let output be an empty string.¶
-For each param_key with a value of param_value in input_parameters:¶
-Append ";" to output.¶
-Append the result of running Serializing a Key (Section 4.1.1.3) with param_key to output.¶
-If param_value is not Boolean true:¶
-Append "=" to output.¶
-Append the result of running Serializing a bare Item (Section 4.1.3.1) with param_value to output.¶
-Return output.¶
-Given a key as input_key, return an ASCII string suitable for use in an HTTP field value.¶
-Convert input_key into a sequence of ASCII characters; if conversion fails, fail serialization.¶
-If input_key contains characters not in lcalpha, DIGIT, "_", "-", ".", or "*", fail serialization.¶
-If the first character of input_key is not lcalpha or "*", fail serialization.¶
-Let output be an empty string.¶
-Append input_key to output.¶
-Return output.¶
-Given an ordered Dictionary as input_dictionary (each member having a member_key and a tuple value of (member_value, parameters)), return an ASCII string suitable for use in an HTTP field value.¶
-Let output be an empty string.¶
-For each member_key with a value of (member_value, parameters) in input_dictionary:¶
-Append the result of running Serializing a Key (Section 4.1.1.3) with member's member_key to output.¶
-If member_value is Boolean true:¶
-Append the result of running Serializing Parameters (Section 4.1.1.2) with parameters to output.¶
-Otherwise:¶
-Append "=" to output.¶
-If member_value is an array, append the result of running Serializing an Inner List (Section 4.1.1.1) with (member_value, parameters) to output.¶
-Otherwise, append the result of running Serializing an Item (Section 4.1.3) with (member_value, parameters) to output.¶
-If more members remain in input_dictionary:¶
- -Return output.¶
-Given an Item as bare_item and Parameters as item_parameters, return an ASCII string suitable for use in an HTTP field value.¶
-Let output be an empty string.¶
-Append the result of running Serializing a Bare Item (Section 4.1.3.1) with bare_item to output.¶
-Append the result of running Serializing Parameters (Section 4.1.1.2) with item_parameters to output.¶
-Return output.¶
-Given an Item as input_item, return an ASCII string suitable for use in an HTTP field value.¶
-If input_item is an Integer, return the result of running Serializing an Integer (Section 4.1.4) with input_item.¶
-If input_item is a Decimal, return the result of running Serializing a Decimal (Section 4.1.5) with input_item.¶
-If input_item is a String, return the result of running Serializing a String (Section 4.1.6) with input_item.¶
-If input_item is a Token, return the result of running Serializing a Token (Section 4.1.7) with input_item.¶
-If input_item is a Byte Sequence, return the result of running Serializing a Byte Sequence (Section 4.1.8) with input_item.¶
-If input_item is a Boolean, return the result of running Serializing a Boolean (Section 4.1.9) with input_item.¶
-If input_item is a Date, return the result of running Serializing a Date (Section 4.1.10) with input_item.¶
-If input_item is a Display String, return the result of running Serializing a Display String (Section 4.1.11) with input_item.¶
-Otherwise, fail serialization.¶
-Given an Integer as input_integer, return an ASCII string suitable for use in an HTTP field value.¶
-If input_integer is not an integer in the range of -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail serialization.¶
-Let output be an empty string.¶
-If input_integer is less than (but not equal to) 0, append "-" to output.¶
-Append input_integer's numeric value represented in base 10 using only decimal digits to output.¶
-Return output.¶
-Given a decimal number as input_decimal, return an ASCII string suitable for use in an HTTP field value.¶
-If input_decimal is not a decimal number, fail serialization.¶
-If input_decimal has more than three significant digits to the right of the decimal point, round it to three decimal places, rounding the final digit to the nearest value, or to the even value if it is equidistant.¶
-If input_decimal has more than 12 significant digits to the left of the decimal point after rounding, fail serialization.¶
-Let output be an empty string.¶
-If input_decimal is less than (but not equal to) 0, append "-" to output.¶
-Append input_decimal's integer component represented in base 10 (using only decimal digits) to output; if it is zero, append "0".¶
-Append "." to output.¶
-If input_decimal's fractional component is zero, append "0" to output.¶
-Otherwise, append the significant digits of input_decimal's fractional component represented in base 10 (using only decimal digits) to output.¶
-Return output.¶
-Given a String as input_string, return an ASCII string suitable for use in an HTTP field value.¶
-Convert input_string into a sequence of ASCII characters; if conversion fails, fail serialization.¶
-If input_string contains characters in the range %x00-1f or %x7f-ff (i.e., not in VCHAR or SP), fail serialization.¶
-Let output be the string DQUOTE.¶
-For each character char in input_string:¶
- -Append DQUOTE to output.¶
-Return output.¶
-Given a Token as input_token, return an ASCII string suitable for use in an HTTP field value.¶
-Convert input_token into a sequence of ASCII characters; if conversion fails, fail serialization.¶
-If the first character of input_token is not ALPHA or "*", or the remaining portion contains a character not in tchar, ":", or "/", fail serialization.¶
-Let output be an empty string.¶
-Append input_token to output.¶
-Return output.¶
-Given a Byte Sequence as input_bytes, return an ASCII string suitable for use in an HTTP field value.¶
-If input_bytes is not a sequence of bytes, fail serialization.¶
-Let output be an empty string.¶
-Append ":" to output.¶
-Append the result of base64-encoding input_bytes as per [RFC4648], Section 4, taking account of the requirements below.¶
-Append ":" to output.¶
-Return output.¶
-The encoded data is required to be padded with "=", as per [RFC4648], Section 3.2.¶
-Likewise, encoded data SHOULD have pad bits set to zero, as per [RFC4648], Section 3.5, unless it is not possible to do so due to implementation constraints.¶
-Given a Boolean as input_boolean, return an ASCII string suitable for use in an HTTP field value.¶
- -Given a Date as input_date, return an ASCII string suitable for use in an HTTP field value.¶
-Let output be "@".¶
-Append to output the result of running Serializing an Integer with input_date (Section 4.1.4).¶
-Return output.¶
-Given a sequence of Unicode codepoints as input_sequence, return an ASCII string suitable for use in an HTTP field value.¶
-If input_sequence is not a sequence of Unicode codepoints, fail serialization.¶
-Let byte_array be the result of applying UTF-8 encoding (Section 3 of [UTF8]) to input_sequence. If encoding fails, fail serialization.¶
-Let encoded_string be a string containing "%" followed by DQUOTE.¶
-For each byte in byte_array:¶
- -Append DQUOTE to encoded_string.¶
-Return encoded_string.¶
-When a receiving implementation parses HTTP fields that are known to be Structured Fields, it is important that care be taken, as there are a number of edge cases that can cause interoperability or even security problems. This section specifies the algorithm for doing so.¶
-Given an array of bytes as input_bytes that represent the chosen field's field-value (which is empty if that field is not present) and field_type (one of "dictionary", "list", or "item"), return the parsed field value.¶
-Convert input_bytes into an ASCII string input_string; if conversion fails, fail parsing.¶
-Discard any leading SP characters from input_string.¶
-If field_type is "list", let output be the result of running Parsing a List (Section 4.2.1) with input_string.¶
-If field_type is "dictionary", let output be the result of running Parsing a Dictionary (Section 4.2.2) with input_string.¶
-If field_type is "item", let output be the result of running Parsing an Item (Section 4.2.3) with input_string.¶
-Discard any leading SP characters from input_string.¶
-If input_string is not empty, fail parsing.¶
-Otherwise, return output.¶
-When generating input_bytes, parsers MUST combine all field lines in the same section (header or trailer) that case-insensitively match the field name into one comma-separated field-value, as per Section 5.2 of [HTTP]; this assures that the entire field value is processed correctly.¶
-For Lists and Dictionaries, this has the effect of correctly concatenating all of the field's lines, as long as individual members of the top-level data structure are not split across multiple field instances. The parsing algorithms for both types allow tab characters, since these might -be used to combine field lines by some implementations.¶
-Strings split across multiple field lines will have unpredictable results, because one or more commas (with optional whitespace) will become part of the string output by the parser. Since concatenation might be done by an upstream intermediary, the results are not under the control of the serializer or the parser, even when they are both under the control of the same party.¶
-Tokens, Integers, Decimals, and Byte Sequences cannot be split across multiple field lines because the inserted commas will cause parsing to fail.¶
-Parsers MAY fail when processing a field value spread across multiple field lines, when one of those lines does not parse as that field. For example, a parsing handling an Example-String field that's defined as an sf-string is allowed to fail when processing this field section:¶
- -If parsing fails, either the entire field value MUST be ignored (i.e., treated as if the field were not present in the section), or alternatively the complete HTTP message MUST be treated as malformed. This is intentionally strict to improve interoperability and safety, and field specifications that use Structured Fields are not allowed to loosen this requirement.¶
-Note that this requirement does not apply to an implementation that is not parsing the field; for example, an intermediary is not required to strip a failing field from a message before forwarding it.¶
-Given an ASCII string as input_string, return an array of (item_or_inner_list, parameters) tuples. input_string is modified to remove the parsed value.¶
-Let members be an empty array.¶
-While input_string is not empty:¶
-Append the result of running Parsing an Item or Inner List (Section 4.2.1.1) with input_string to members.¶
-Discard any leading OWS characters from input_string.¶
-If input_string is empty, return members.¶
-Consume the first character of input_string; if it is not ",", fail parsing.¶
-Discard any leading OWS characters from input_string.¶
-If input_string is empty, there is a trailing comma; fail parsing.¶
-No structured data has been found; return members (which is empty).¶
-Given an ASCII string as input_string, return the tuple (item_or_inner_list, parameters), where item_or_inner_list can be either a single bare item or an array of (bare_item, parameters) tuples. input_string is modified to remove the parsed value.¶
-If the first character of input_string is "(", return the result of running Parsing an Inner List (Section 4.2.1.2) with input_string.¶
-Return the result of running Parsing an Item (Section 4.2.3) with input_string.¶
-Given an ASCII string as input_string, return the tuple (inner_list, parameters), where inner_list is an array of (bare_item, parameters) tuples. input_string is modified to remove the parsed value.¶
-Consume the first character of input_string; if it is not "(", fail parsing.¶
-Let inner_list be an empty array.¶
-While input_string is not empty:¶
-Discard any leading SP characters from input_string.¶
-If the first character of input_string is ")":¶
-Consume the first character of input_string.¶
-Let parameters be the result of running Parsing Parameters (Section 4.2.3.2) with input_string.¶
-Return the tuple (inner_list, parameters).¶
-Let item be the result of running Parsing an Item (Section 4.2.3) with input_string.¶
-Append item to inner_list.¶
-If the first character of input_string is not SP or ")", fail parsing.¶
-The end of the Inner List was not found; fail parsing.¶
-Given an ASCII string as input_string, return an ordered map whose values are (item_or_inner_list, parameters) tuples. input_string is modified to remove the parsed value.¶
-Let dictionary be an empty, ordered map.¶
-While input_string is not empty:¶
-Let this_key be the result of running Parsing a Key (Section 4.2.3.3) with input_string.¶
-If the first character of input_string is "=":¶
-Consume the first character of input_string.¶
-Let member be the result of running Parsing an Item or Inner List (Section 4.2.1.1) with input_string.¶
-Otherwise:¶
-Let value be Boolean true.¶
-Let parameters be the result of running Parsing Parameters (Section 4.2.3.2) with input_string.¶
-Let member be the tuple (value, parameters).¶
-If dictionary already contains a key this_key (comparing character for character), overwrite its value with member.¶
-Otherwise, append key this_key with value member to dictionary.¶
-Discard any leading OWS characters from input_string.¶
-If input_string is empty, return dictionary.¶
-Consume the first character of input_string; if it is not ",", fail parsing.¶
-Discard any leading OWS characters from input_string.¶
-If input_string is empty, there is a trailing comma; fail parsing.¶
-No structured data has been found; return dictionary (which is empty).¶
-Note that when duplicate Dictionary keys are encountered, all but the last instance are ignored.¶
-Given an ASCII string as input_string, return a (bare_item, parameters) tuple. input_string is modified to remove the parsed value.¶
-Let bare_item be the result of running Parsing a Bare Item (Section 4.2.3.1) with input_string.¶
-Let parameters be the result of running Parsing Parameters (Section 4.2.3.2) with input_string.¶
-Return the tuple (bare_item, parameters).¶
-Given an ASCII string as input_string, return a bare Item. input_string is modified to remove the parsed value.¶
-If the first character of input_string is a "-" or a DIGIT, return the result of running Parsing an Integer or Decimal (Section 4.2.4) with input_string.¶
-If the first character of input_string is a DQUOTE, return the result of running Parsing a String (Section 4.2.5) with input_string.¶
-If the first character of input_string is an ALPHA or "*", return the result of running Parsing a Token (Section 4.2.6) with input_string.¶
-If the first character of input_string is ":", return the result of running Parsing a Byte Sequence (Section 4.2.7) with input_string.¶
-If the first character of input_string is "?", return the result of running Parsing a Boolean (Section 4.2.8) with input_string.¶
-If the first character of input_string is "@", return the result of running Parsing a Date (Section 4.2.9) with input_string.¶
-If the first character of input_string is "%", return the result of running Parsing a Display String (Section 4.2.10) with input_string.¶
-Otherwise, the item type is unrecognized; fail parsing.¶
-Given an ASCII string as input_string, return an ordered map whose values are bare Items. input_string is modified to remove the parsed value.¶
-Let parameters be an empty, ordered map.¶
-While input_string is not empty:¶
-If the first character of input_string is not ";", exit the loop.¶
-Consume the ";" character from the beginning of input_string.¶
-Discard any leading SP characters from input_string.¶
-Let param_key be the result of running Parsing a Key (Section 4.2.3.3) with input_string.¶
-Let param_value be Boolean true.¶
-If the first character of input_string is "=":¶
-Consume the "=" character at the beginning of input_string.¶
-Let param_value be the result of running Parsing a Bare Item (Section 4.2.3.1) with input_string.¶
-If parameters already contains a key param_key (comparing character for character), overwrite its value with param_value.¶
-Otherwise, append key param_key with value param_value to parameters.¶
-Return parameters.¶
-Note that when duplicate parameter keys are encountered, all but the last instance are ignored.¶
-Given an ASCII string as input_string, return a key. input_string is modified to remove the parsed value.¶
- -Given an ASCII string as input_string, return an Integer or Decimal. input_string is modified to remove the parsed value.¶
-NOTE: This algorithm parses both Integers (Section 3.3.1) and Decimals (Section 3.3.2), and returns the corresponding structure.¶
-Let type be "integer".¶
-Let sign be 1.¶
-Let input_number be an empty string.¶
-If the first character of input_string is "-", consume it and set sign to -1.¶
-If input_string is empty, there is an empty integer; fail parsing.¶
-If the first character of input_string is not a DIGIT, fail parsing.¶
-While input_string is not empty:¶
-Let char be the result of consuming the first character of input_string.¶
-If char is a DIGIT, append it to input_number.¶
-Else, if type is "integer" and char is ".":¶
- -Otherwise, prepend char to input_string, and exit the loop.¶
-If type is "integer" and input_number contains more than 15 characters, fail parsing.¶
-If type is "decimal" and input_number contains more than 16 characters, fail parsing.¶
-If type is "integer":¶
-Let output_number be an Integer that is the result of parsing input_number as an integer.¶
-Otherwise:¶
- -Let output_number be the product of output_number and sign.¶
-Return output_number.¶
-Given an ASCII string as input_string, return an unquoted String. input_string is modified to remove the parsed value.¶
-Let output_string be an empty string.¶
-If the first character of input_string is not DQUOTE, fail parsing.¶
-Discard the first character of input_string.¶
-While input_string is not empty:¶
-Let char be the result of consuming the first character of input_string.¶
-If char is a backslash ("\"):¶
- -Else, if char is DQUOTE, return output_string.¶
-Else, if char is in the range %x00-1f or %x7f-ff (i.e., it is not in VCHAR or SP), fail parsing.¶
-Else, append char to output_string.¶
-Reached the end of input_string without finding a closing DQUOTE; fail parsing.¶
-Given an ASCII string as input_string, return a Token. input_string is modified to remove the parsed value.¶
- -Given an ASCII string as input_string, return a Byte Sequence. input_string is modified to remove the parsed value.¶
-If the first character of input_string is not ":", fail parsing.¶
-Discard the first character of input_string.¶
-If there is not a ":" character before the end of input_string, fail parsing.¶
-Let b64_content be the result of consuming content of input_string up to but not including the first instance of the character ":".¶
-Consume the ":" character at the beginning of input_string.¶
-If b64_content contains a character not included in ALPHA, DIGIT, "+", "/", and "=", fail parsing.¶
-Let binary_content be the result of base64-decoding [RFC4648] b64_content, synthesizing padding if necessary (note the requirements about recipient behavior below). If base64 decoding fails, parsing fails.¶
-Return binary_content.¶
-Because some implementations of base64 do not allow rejection of encoded data that is not properly "=" padded (see [RFC4648], Section 3.2), parsers SHOULD NOT fail when "=" padding is not present, unless they cannot be configured to do so.¶
-Because some implementations of base64 do not allow rejection of encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), parsers SHOULD NOT fail when non-zero pad bits are present, unless they cannot be configured to do so.¶
-This specification does not relax the requirements in Sections 3.1 and 3.3 of [RFC4648]; therefore, parsers MUST fail on characters outside the base64 alphabet and on line feeds in encoded data.¶
-Given an ASCII string as input_string, return a Boolean. input_string is modified to remove the parsed value.¶
-If the first character of input_string is not "?", fail parsing.¶
-Discard the first character of input_string.¶
-If the first character of input_string matches "1", discard the first character, and return true.¶
-If the first character of input_string matches "0", discard the first character, and return false.¶
-No value has matched; fail parsing.¶
-Given an ASCII string as input_string, return a Date. input_string is modified to remove the parsed value.¶
-If the first character of input_string is not "@", fail parsing.¶
-Discard the first character of input_string.¶
-Let output_date be the result of running Parsing an Integer or Decimal (Section 4.2.4) with input_string.¶
-If output_date is a Decimal, fail parsing.¶
-Return output_date.¶
-Given an ASCII string as input_string, return a sequence of Unicode codepoints. input_string is modified to remove the parsed value.¶
-If the first two characters of input_string are not "%" followed by DQUOTE, fail parsing.¶
-Discard the first two characters of input_string.¶
-Let byte_array be an empty byte array.¶
-While input_string is not empty:¶
-Let char be the result of consuming the first character of input_string.¶
-If char is in the range %x00-1f or %x7f-ff (i.e., it is not in VCHAR or SP), fail parsing.¶
-If char is "%":¶
-Let octet_hex be the result of consuming two characters from input_string. If there are not two characters, fail parsing.¶
-If octet_hex contains characters outside the range %x30-39 or %x61-66 (i.e., it is not in 0-9 or lowercase a-f), fail parsing.¶
-Let octet be the result of hex decoding octet_hex (Section 8 of [RFC4648]).¶
-Append octet to byte_array.¶
-If char is DQUOTE:¶
- -Otherwise, if char is not "%" or DQUOTE:¶
- -Reached the end of input_string without finding a closing DQUOTE; fail parsing.¶
-Please add the following note to the "Hypertext Transfer Protocol (HTTP) Field Name Registry":¶
-The "Structured Type" column indicates the type of the field (per RFC nnnn), if any, and may be -"Dictionary", "List" or "Item".¶
-Note that field names beginning with characters other than ALPHA or "*" will not be able to be -represented as a Structured Fields Token, and therefore may be incompatible with being mapped into -fields that refer to it.¶
-Then, add a new column, "Structured Type".¶
-Then, add the indicated Structured Type for each existing registry entry listed in Table 1.¶
-Field Name | -Structured Type | -
---|---|
Accept-CH | -List | -
Cache-Status | -List | -
CDN-Cache-Control | -Dictionary | -
Cross-Origin-Embedder-Policy | -Item | -
Cross-Origin-Embedder-Policy-Report-Only | -Item | -
Cross-Origin-Opener-Policy | -Item | -
Cross-Origin-Opener-Policy-Report-Only | -Item | -
Origin-Agent-Cluster | -Item | -
Priority | -Dictionary | -
Proxy-Status | -List | -
The size of most types defined by Structured Fields is not limited; as a result, extremely large fields could be an attack vector (e.g., for resource consumption). Most HTTP implementations limit the sizes of individual fields as well as the overall header or trailer section size to mitigate such attacks.¶
-It is possible for parties with the ability to inject new HTTP fields to change the meaning -of a Structured Field. In some circumstances, this will cause parsing to fail, but it is not possible to reliably fail in all such circumstances.¶
-The Display String type can convey any possible Unicode code point without sanitization; for example, they might contain unassigned code points, control points (including NUL), or noncharacters. Therefore, applications consuming Display Strings need to consider strategies such as filtering or escaping untrusted content before displaying it. See also [UNICODE-SECURITY] and [I-D.draft-bray-unichars].¶
-Earlier proposals for Structured Fields were based upon JSON [RFC8259]. However, constraining its use to make it suitable for HTTP fields required senders and recipients to implement specific additional handling.¶
-For example, JSON has specification issues around large numbers and objects with duplicate members. Although advice for avoiding these issues is available (e.g., [RFC7493]), it cannot be relied upon.¶
-Likewise, JSON strings are by default Unicode strings, which have a number of potential interoperability issues (e.g., in comparison). Although implementers can be advised to avoid non-ASCII content where unnecessary, this is difficult to enforce.¶
-Another example is JSON's ability to nest content to arbitrary depths. Since the resulting memory commitment might be unsuitable (e.g., in embedded and other limited server deployments), it's necessary to limit it in some fashion; however, existing JSON implementations have no such limits, and even if a limit is specified, it's likely that some field definition will find a need to violate it.¶
-Because of JSON's broad adoption and implementation, it is difficult to impose such additional constraints across all implementations; some deployments would fail to enforce them, thereby harming interoperability. In short, if it looks like JSON, people will be tempted to use a JSON parser/serializer on field values.¶
-Since a major goal for Structured Fields is to improve interoperability and simplify implementation, these concerns led to a format that requires a dedicated parser and serializer.¶
-Additionally, there were widely shared feelings that JSON doesn't "look right" in HTTP fields.¶
-A generic implementation of this specification should expose the top-level serialize (Section 4.1) and parse (Section 4.2) functions. They need not be functions; for example, it could be implemented as an object, with methods for each of the different top-level types.¶
-For interoperability, it's important that generic implementations be complete and follow the algorithms closely; see Section 1.1. To aid this, a common test suite is being maintained by the community at <https://github.com/httpwg/structured-field-tests>.¶
-Implementers should note that Dictionaries and Parameters are order-preserving maps. Some fields may not convey meaning in the ordering of these data types, but it should still be exposed so that it will be available to applications that need to use it.¶
-Likewise, implementations should note that it's important to preserve the distinction between Tokens and Strings. While most programming languages have native types that map to the other types well, it may be necessary to create a wrapper "token" object or use a parameter on functions to assure that these types remain separate.¶
-The serialization algorithm is defined in a way that it is not strictly limited to the data types defined in Section 3 in every case. For example, Decimals are designed to take broader input and round to allowed values.¶
-Implementations are allowed to limit the size of different structures, subject to the minimums defined for each type. When a structure exceeds an implementation limit, that structure fails parsing or serialization.¶
-This section uses the Augmented Backus-Naur Form (ABNF) notation [RFC5234] to illustrate expected syntax of Structured Fields. However, it cannot be used to validate their syntax, because it does not capture all requirements.¶
-This section is non-normative. If there is disagreement between the parsing algorithms and ABNF, the specified algorithms take precedence.¶
--sf-list = list-member *( OWS "," OWS list-member ) -list-member = sf-item / inner-list - -inner-list = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")" - parameters - -parameters = *( ";" *SP parameter ) -parameter = param-key [ "=" param-value ] -param-key = key -key = ( lcalpha / "*" ) - *( lcalpha / DIGIT / "_" / "-" / "." / "*" ) -lcalpha = %x61-7A ; a-z -param-value = bare-item - -sf-dictionary = dict-member *( OWS "," OWS dict-member ) -dict-member = member-key ( parameters / ( "=" member-value )) -member-key = key -member-value = sf-item / inner-list - -sf-item = bare-item parameters -bare-item = sf-integer / sf-decimal / sf-string / sf-token - / sf-binary / sf-boolean / sf-date / sf-displaystring - -sf-integer = ["-"] 1*15DIGIT -sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT -sf-string = DQUOTE *( unescaped / "%" / bs-escaped ) DQUOTE -sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" ) -sf-binary = ":" base64 ":" -sf-boolean = "?" ( "0" / "1" ) -sf-date = "@" sf-integer -sf-displaystring = "%" DQUOTE *( unescaped / "\" / pct-encoded ) - DQUOTE - -base64 = *( ALPHA / DIGIT / "+" / "/" ) *"=" - -unescaped = %x20-21 / %x23-24 / %x26-5B / %x5D-7E -bs-escaped = "\" ( DQUOTE / "\" ) - -pct-encoded = "%" lc-hexdig lc-hexdig -lc-hexdig = DIGIT / %x61-66 ; 0-9, a-f -¶ -
This revision of the Structured Field Values for HTTP specification has made the following changes:¶
-Added the Date structured type. (Section 3.3.7)¶
-Stopped encouraging use of ABNF in definitions of new structured fields. (Section 2)¶
-Moved ABNF to an informative appendix. (Appendix C)¶
-Added a "Structured Type" column to the HTTP Field Name Registry. (Section 5)¶
-Refined parse failure handling. (Section 4.2)¶
-Added the Display String structured type. (Section 3.3.8)¶
-Many thanks to Matthew Kerwin for his detailed feedback and careful consideration during the development of this specification.¶
-Thanks also to Ian Clelland, Roy Fielding, Anne van Kesteren, Kazuho Oku, Evert Pot, Julian Reschke, Martin Thomson, Mike West, and Jeffrey Yasskin for their contributions.¶
-Internet-Draft | -The Signature HTTP Authentication Scheme | -January 2024 | -
Schinazi, et al. | -Expires 27 July 2024 | -[Page] | -
Existing HTTP authentication schemes are probeable in the sense that it is -possible for an unauthenticated client to probe whether an origin serves -resources that require authentication. It is possible for an origin to hide the -fact that it requires authentication by not generating Unauthorized status -codes, however that only works with non-cryptographic authentication schemes: -cryptographic signatures require a fresh nonce to be signed, and there is no -existing way for the origin to share such a nonce without exposing the fact -that it serves resources that require authentication. This document proposes a -new non-probeable cryptographic authentication scheme.¶
-This note is to be removed before publishing as an RFC.¶
-- The latest revision of this draft can be found at https://httpwg.org/http-extensions/draft-ietf-httpbis-unprompted-auth.html. - Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-unprompted-auth/.¶
-- Discussion of this document takes place on the - HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), - which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. - Working Group information can be found at https://httpwg.org/.¶
-Source for this draft and an issue tracker can be found at - https://github.com/httpwg/http-extensions/labels/unprompted-auth.¶
-- This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79.¶
-- Internet-Drafts are working documents of the Internet Engineering Task - Force (IETF). Note that other groups may also distribute working - documents as Internet-Drafts. The list of current Internet-Drafts is - at https://datatracker.ietf.org/drafts/current/.¶
-- Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress."¶
-- This Internet-Draft will expire on 27 July 2024.¶
-- Copyright (c) 2024 IETF Trust and the persons identified as the - document authors. All rights reserved.¶
-- This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents - (https://trustee.ietf.org/license-info) in effect on the date of - publication of this document. Please review these documents - carefully, as they describe your rights and restrictions with - respect to this document. Code Components extracted from this - document must include Revised BSD License text as described in - Section 4.e of the Trust Legal Provisions and are provided without - warranty as described in the Revised BSD License.¶
-HTTP authentication schemes (see Section 11 of [HTTP]) allow origins -to restrict access for some resources to only authenticated requests. While -these schemes commonly involve a challenge where the origin asks the client to -provide authentication information, it is possible for clients to send such -information unprompted. This is particularly useful in cases where an origin -wants to offer a service or capability only to "those who know" while all -others are given no indication the service or capability exists. Such designs -rely on an externally-defined mechanism by which keys are distributed. For -example, a company might offer remote employee access to company services -directly via its website using their employee credentials, or offer access to -limited special capabilities for specific employees, while making discovering -(probing for) such capabilities difficult. Members of less well-defined -communities might use more ephemeral keys to acquire access to geography- or -capability-specific resources, as issued by an entity whose user base is larger -than the available resources can support (by having that entity metering the -availability of keys temporally or geographically).¶
-While digital-signature-based HTTP authentication schemes already exist -([HOBA]), they rely on the origin explicitly sending a fresh -challenge to the client, to ensure that the signature input is fresh. That -makes the origin probeable as it send the challenge to unauthenticated clients. -This document defines a new signature-based authentication scheme that is not -probeable.¶
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", -"MAY", and "OPTIONAL" in this document are to be interpreted as -described in BCP 14 [RFC2119] [RFC8174] when, and only when, they -appear in all capitals, as shown here.¶
-This document uses the notation from Section 1.3 of [QUIC].¶
-This document defines the "Signature" HTTP authentication scheme. It uses -asymmetric cryptography. User agents possess a key ID and a public/private key -pair, and origin servers maintain a mapping of authorized key IDs to their -associated public keys.¶
-The client uses a TLS keying material exporter to generate data to be signed -(see Section 4) then sends the signature using the Authorization or -Proxy-Authorization header field. The signature and additional information are -exchanged using authentication parameters (see Section 5).¶
-This authentication scheme is only defined for uses of HTTP with TLS -[TLS]. This includes any use of HTTP over TLS as typically used for -HTTP/2 [HTTP/2], or HTTP/3 [HTTP/3] where the transport protocol uses TLS as its -authentication and key exchange mechanism [QUIC-TLS].¶
-Because the TLS keying material exporter is only secure for authentication when -it is uniquely bound to the TLS session [RFC7627], the Signature -authentication scheme requires either one of the following properties:¶
-The TLS version in use is 1.2 and the Extended Master Secret extension -[RFC7627] has been negotiated.¶
-Clients MUST NOT use the Signature authentication scheme on connections that do -not meet one of the two properties above. If a server receives a request that -uses this authentication scheme on a connection that meets neither of the above -properties, the server MUST treat the request as malformed.¶
-The user agent computes the authentication proof using a TLS keying material -exporter [KEY-EXPORT] with the following parameters:¶
-the label is set to "EXPORTER-HTTP-Signature-Authentication"¶
-the context is set to the structure described in Section 4.1¶
-the exporter output length is set to 48 bytes (see Section 4.2)¶
-The TLS key exporter context is described in Figure 1:¶
-- Signature Algorithm (16), - Key ID Length (i), - Key ID (..), - Public Key Length (i), - Public Key (..), - Scheme Length (i), - Scheme (..), - Host Length (i), - Host (..), - Port (16), - Realm Length (i), - Realm (..), --
The key exporter context contains the following fields:¶
-The signature scheme sent in the s
Parameter (see Section 5.4).¶
The key ID sent in the k
Parameter (see Section 5.1).¶
The public key used by the server to validate the signature provided by the -client (the encoding is described below).¶
-The scheme for this request, encoded using the format of the scheme portion -of a URI as defined in Section 3.1 of [URI].¶
-The host for this request, encoded using the format of the host portion of a -URI as defined in Section 3.2.2 of [URI].¶
-The port for this request, encoded in network byte order. Note that the port -is either included in the URI, or is the default port for the scheme in use; -see Section 3.2.3 of [URI].¶
-The real of authentication that is sent in the realm authentication parameter -(Section 11.5 of [HTTP]). If the realm authentication parameter is not -present, this SHALL be empty. This document does not define a means for the -origin to communicate a realm to the client. If a client is not configured to -use a specific realm, it SHALL use an empty realm and SHALL NOT send the realm -authentication parameter.¶
-The Signature Algorithm and Port fields are encoded as unsigned 16-bit integers -in network byte order. The Key ID, Public Key, Scheme, Host, and Real fields -are length prefixed strings; they are preceded by a Length field that -represents their length in bytes. These length fields are encoded using the -variable-length integer encoding from Section 16 of [QUIC] and MUST be -encoded in the minimum number of bytes necessary.¶
-The encoding of the public key is determined by the Signature Algorithm in use -as follows:¶
-The public key is an RSAPublicKey structure [PKCS1] encoded in DER -[X.690]. BER encodings which are not DER MUST be rejected.¶
-The public key is a UncompressedPointRepresentation structure defined in -Section 4.2.8.2 of [TLS], using the curve specified by the SignatureScheme.¶
-The public key is the byte string encoding defined in [EdDSA].¶
-This document does not define the public key encodings for other algorithms. In -order for a SignatureScheme to be usable with the Signature HTTP authentication -scheme, its public key encoding needs to be defined in a corresponding document.¶
-The key exporter output is 48 bytes long. Of those, the first 32 bytes are part -of the input to the signature and the next 16 bytes are sent alongside the -signature. This allows the recipient to confirm that the exporter produces the -right values. This is described in Figure 2:¶
-- Signature Input (256), - Verification (128), --
The key exporter context contains the following fields:¶
-This is part of the data signed using the client's chosen asymmetric private -key (see Section 4.3).¶
-The verification is transmitted to the server using the v Parameter (see -Section 5.5).¶
-Once the Signature Input has been extracted from the key exporter output (see -Section 4.2), it is prefixed with static data before being signed to mitigate -issues caused by key reuse. The signature is computed over the concatenation of:¶
-A string that consists of octet 32 (0x20) repeated 64 times¶
-The context string "HTTP Signature Authentication"¶
-A single 0 byte which serves as a separator¶
-The Signature Input extracted from the key exporter output (see Section 4.2)¶
-For example, if the Signature Input has all its 32 bytes set to 01, the content -covered by the signature (in hexadecimal format) would be:¶
--2020202020202020202020202020202020202020202020202020202020202020 -2020202020202020202020202020202020202020202020202020202020202020 -48545450205369676E61747572652041757468656E7469636174696F6E -00 -0101010101010101010101010101010101010101010101010101010101010101 --
This constructions mirrors that of the TLS 1.3 CertificateVerify message -defined in Section 4.4.3 of [TLS].¶
-The resulting signature is then transmitted to the server using the p
-Parameter (see Section 5.3).¶
This specification defines the following authentication parameters.¶
-All of the byte sequences below are encoded using base64url (see Section 5 of [BASE64]) without quotes and without padding. In other words, these -byte sequence authentication parameters values MUST NOT include any characters -other then ASCII letters, digits, dash and underscore.¶
-The integer below is encoded without a minus and without leading zeroes. In -other words, the integer authentication parameters value MUST NOT include any -characters other than digits, and MUST NOT start with a zero unless the full -value is "0".¶
-Using the syntax from [ABNF]:¶
--signature-byte-sequence-param-value = *( ALPHA / DIGIT / "-" / "_" ) -signature-integer-param-value = %x31-39 1*4( DIGIT ) / "0" --
The REQUIRED "k" (key ID) parameter is a byte sequence that identifies which key -the user agent wishes to use to authenticate. This can for example be used to -point to an entry into a server-side database of known keys.¶
-The REQUIRED "a" (public key) parameter is a byte sequence that contains the -public key used by the server to validate the signature provided by the client. -This avoids key confusion issues (see [SEEMS-LEGIT]). The encoding of the -public key is described in Section 4.1.¶
-The REQUIRED "p" (proof) parameter is a byte sequence that specifies the proof -that the user agent provides to attest to possessing the credential that matches -its key ID.¶
-The REQUIRED "s" (signature) parameter is an integer that specifies the -signature scheme used to compute the proof transmitted in the "p" directive. -Its value is an integer between 0 and 65535 inclusive from the IANA "TLS -SignatureScheme" registry maintained at -<https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-signaturescheme>.¶
-The REQUIRED "v" (verification) parameter is a byte sequence that specifies the -verification that the user agent provides to attest to possessing the key -exporter output (see Section 4.2 for details). This avoids issues with signature -schemes where certain keys can generate signatures that are valid for multiple -inputs (see [SEEMS-LEGIT]).¶
-For example, the key ID "basement" authenticating using Ed25519 -[ED25519] could produce the following header field:¶
-Servers that wish to introduce resources whose existence cannot be probed need -to ensure that they do not reveal any information about those resources to -unauthenticated clients. In particular, such servers MUST respond to -authentication failures with the exact same response that they would have used -for non-existent resources. For example, this can mean using HTTP status code -404 (Not Found) instead of 401 (Unauthorized). Such authentication failures -can be caused for example by:¶
-absence of the Authorization (or Proxy-Authorization) field¶
-failure to parse that field¶
-use of the Signature authentication scheme with an unknown key ID¶
-mismatch between key ID and provided public key¶
-failure to validate the verification parameter¶
-failure to validate the signature.¶
-In order to validate the signature, the server needs to first parse the field -containing the signature, then look up the key ID in its database of public -keys, and finally perform the cryptographic validation. These steps can take -time, and an attacker could detect use of this mechanism if that time is -observable by comparing the timing of a request for a known non-existent -resource to the timing of a request for a potentially authenticated resource. -Servers can mitigate this observability by slightly delaying responses to some -non-existent resources such that the timing of the authentication verification -is not observable. This delay needs to be carefully considered to avoid having -the delay itself leak the fact that this origin uses this mechanism at all.¶
-Non-probeable resources also need to be non-discoverable for unauthenticated -users. For example, if a server operator wishes to hide an authenticated -resource by pretending it does not exist to unauthenticated users, then the -server operator needs to ensure there are no unauthenticated pages with links -to that resource, and no other out-of-band ways for unauthenticated users to -discover this resource.¶
-Since the Signature HTTP authentication scheme leverages TLS keying material -exporters, its output cannot be transparently forwarded by HTTP intermediaries. -HTTP intermediaries that support this specification have two options:¶
-The intermediary can validate the authentication received from the client, -then inform the upstream HTTP server of the presence of valid authentication.¶
-The intermediary can export the Signature Input and Verification (see -Section 4.2}), and forward it to the upstream HTTP server, then the upstream -server performs the validation.¶
-The mechanism for the intermediary to communicate this information to the -upstream HTTP server is out of scope for this document.¶
-Note that both of these mechanisms require the upstream HTTP server to trust -the intermediary. This is usually the case because the intermediary already -needs access to the TLS certificate private key in order to respond to requests.¶
-The Signature HTTP authentication scheme allows a user agent to authenticate to -an origin server while guaranteeing freshness and without the need for the -server to transmit a nonce to the user agent. This allows the server to accept -authenticated clients without revealing that it supports or expects -authentication for some resources. It also allows authentication without the -user agent leaking the presence of authentication to observers due to -clear-text TLS Client Hello extensions.¶
-The authentication proofs described in this document are not bound to -individual HTTP requests; if the key is used for authentication proofs on -multiple requests on the same connection, they will all be identical. This -allows for better compression when sending over the wire, but implies that -client implementations that multiplex different security contexts over a single -HTTP connection need to ensure that those contexts cannot read each other's -header fields. Otherwise, one context would be able to replay the Authorization -header field of another. This constraint is met by modern Web browsers. If an -attacker were to compromise the browser such that it could access another -context's memory, the attacker might also be able to access the corresponding -key, so binding authentication to requests would not provide much benefit in -practice.¶
-Key material used for the Signature HTTP authentication scheme MUST NOT be -reused in other protocols. Doing so can undermine the security guarantees of -the authentication.¶
-Origins offering this scheme can link requests that use the same key. -However, requests are not linkable across origins if the keys used are specific -to the individual origins using this scheme.¶
-This document, if approved, requests IANA to register the following entry in -the "HTTP Authentication Schemes" Registry maintained at -<https://www.iana.org/assignments/http-authschemes>:¶
- -This document, if approved, requests IANA to register the following entry in -the "TLS Exporter Labels" registry maintained at -<https://www.iana.org/assignments/tls-parameters#exporter-labels>:¶
- -The authors would like to thank many members of the IETF community, as this -document is the fruit of many hallway conversations. In particular, the authors -would like to thank David Benjamin, Nick Harper, Dennis Jackson, Ilari Liusvaara, François Michel, Lucas Pardue, -Justin Richer, Ben Schwartz, Martin Thomson, and -Chris A. Wood for their reviews and contributions. The mechanism -described in this document was originally part of the first iteration of MASQUE -[MASQUE-ORIGINAL].¶
-