idnits 2.17.1 draft-west-http-state-tokens-00.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack a Security Considerations section. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (March 28, 2019) is 1853 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 894 -- Possible downref: Non-RFC (?) normative reference: ref. 'Fetch' == Outdated reference: A later version (-19) exists of draft-ietf-httpbis-header-structure-09 == Outdated reference: A later version (-09) exists of draft-yasskin-http-origin-signed-responses-05 -- Possible downref: Non-RFC (?) normative reference: ref. 'Mixed-Content' ** Downref: Normative reference to an Informational RFC: RFC 2104 ** Obsolete normative reference: RFC 2109 (Obsoleted by RFC 2965) ** Obsolete normative reference: RFC 7230 (Obsoleted by RFC 9110, RFC 9112) ** Downref: Normative reference to an Experimental RFC: RFC 7409 Summary: 5 errors (**), 0 flaws (~~), 3 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group M. West 3 Internet-Draft Google 4 Intended status: Standards Track March 28, 2019 5 Expires: September 29, 2019 7 HTTP State Tokens 8 draft-west-http-state-tokens-00 10 Abstract 12 This document describes a mechanism which allows HTTP servers to 13 maintain stateful sessions with HTTP user agents. It aims to address 14 some of the security and privacy considerations which have been 15 identified in existing state management mechanisms, providing 16 developers with a well-lit path towards our current understanding of 17 best practice. 19 Status of This Memo 21 This Internet-Draft is submitted in full conformance with the 22 provisions of BCP 78 and BCP 79. 24 Internet-Drafts are working documents of the Internet Engineering 25 Task Force (IETF). Note that other groups may also distribute 26 working documents as Internet-Drafts. The list of current Internet- 27 Drafts is at https://datatracker.ietf.org/drafts/current/. 29 Internet-Drafts are draft documents valid for a maximum of six months 30 and may be updated, replaced, or obsoleted by other documents at any 31 time. It is inappropriate to use Internet-Drafts as reference 32 material or to cite them other than as "work in progress." 34 This Internet-Draft will expire on September 29, 2019. 36 Copyright Notice 38 Copyright (c) 2019 IETF Trust and the persons identified as the 39 document authors. All rights reserved. 41 This document is subject to BCP 78 and the IETF Trust's Legal 42 Provisions Relating to IETF Documents 43 (https://trustee.ietf.org/license-info) in effect on the date of 44 publication of this document. Please review these documents 45 carefully, as they describe your rights and restrictions with respect 46 to this document. Code Components extracted from this document must 47 include Simplified BSD License text as described in Section 4.e of 48 the Trust Legal Provisions and are provided without warranty as 49 described in the Simplified BSD License. 51 Table of Contents 53 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 54 1.1. Wait. Don't we have cookies? . . . . . . . . . . . . . . 3 55 1.2. No. Really. We have cookies already. Why do we need this 56 new thing? . . . . . . . . . . . . . . . . . . . . . . . 4 57 1.3. Examples . . . . . . . . . . . . . . . . . . . . . . . . 5 58 2. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . 5 59 2.1. Conformance . . . . . . . . . . . . . . . . . . . . . . . 5 60 2.2. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 5 61 3. Infrastructure . . . . . . . . . . . . . . . . . . . . . . . 5 62 3.1. HTTP State Tokens . . . . . . . . . . . . . . . . . . . . 5 63 3.2. Requests and Responses . . . . . . . . . . . . . . . . . 6 64 3.3. Token Storage . . . . . . . . . . . . . . . . . . . . . . 7 65 4. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 66 4.1. The 'Sec-Http-State' HTTP Header Field . . . . . . . . . 8 67 4.2. The 'Sec-Http-State-Options' HTTP Header Field . . . . . 9 68 5. Delivering HTTP State Tokens . . . . . . . . . . . . . . . . 11 69 5.1. Attach HTTP State Tokens to a request . . . . . . . . . . 11 70 5.2. Generate a request's signature . . . . . . . . . . . . . 12 71 6. Configuring HTTP State Tokens . . . . . . . . . . . . . . . . 13 72 7. Security and Privacy Considerations . . . . . . . . . . . . . 15 73 7.1. Confidentiality and Integrity . . . . . . . . . . . . . . 15 74 7.2. Signed Sessions . . . . . . . . . . . . . . . . . . . . . 16 75 7.3. User Control . . . . . . . . . . . . . . . . . . . . . . 16 76 7.4. Lifetime . . . . . . . . . . . . . . . . . . . . . . . . 16 77 7.5. Ambient Authority and Cross-Site Delivery . . . . . . . . 16 78 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 17 79 8.1. Header Field Registry . . . . . . . . . . . . . . . . . . 17 80 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 18 81 9.1. Normative References . . . . . . . . . . . . . . . . . . 18 82 9.2. Informative References . . . . . . . . . . . . . . . . . 19 83 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 19 84 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 19 85 Appendix B. Changes . . . . . . . . . . . . . . . . . . . . . . 20 86 B.1. Since the beginning of time . . . . . . . . . . . . . . . 20 87 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 20 89 1. Introduction 91 This document defines a state-management mechanism for HTTP that 92 allows clients to create and persist origin-bound session identifiers 93 that can be delivered to servers in order to enable stateful 94 interaction. In a nutshell, each user agent will generate a single 95 token per secure origin, and will deliver it as a "Sec-Http-State" 96 structured header along with requests to that origin (defined in 97 Section 4.1 and Section 5). 99 Servers can configure this token's characteristics via a "Sec-Http- 100 State-Options" response header (defined in Section 4.2 and 101 Section 6). 103 That's it. 105 1.1. Wait. Don't we have cookies? 107 Cookies [RFC6265] are indeed a pervasive HTTP state management 108 mechanism, and they enable practically everything interesting on the 109 web today. That said, cookies have some issues: they're hard to use 110 securely, they add substantial weight to users' outgoing requests, 111 and they enable tracking users' activity across the web in 112 potentially surprising ways. 114 The mechanism proposed in this document aims at a more minimal and 115 opinionated construct which takes inspiration from some of cookies' 116 optional characteristics. In particular: 118 1. The client controls the token's value, not the server. 120 2. The token will only be available to the network layer, not to 121 JavaScript (including network-like JavaScript, such as Service 122 Workers). 124 3. The user agent will generate only one token per origin, and will 125 only expose the token to the origin for which it was generated. 127 4. Tokens will not be generated for, or delivered to, non-secure 128 origins. 130 5. Tokens will be delivered only along with same-site requests by 131 default, and can only be created from same-site contexts. 133 6. Each token persists for one hour after generation by default. 134 This default expiration time can be overwritten by servers, and 135 tokens can be reset at any time by servers, users, or user 136 agents. 138 These distinctions might not be appropriate for all use cases, but 139 seem like a reasonable set of defaults. For folks for whom these 140 defaults aren't good enough, we'll provide developers with a few 141 control points that can be triggered via a "Sec-HTTP-State-Options" 142 HTTP response header, described in Section 4.2. 144 1.2. No. Really. We have cookies already. Why do we need this new 145 thing? 147 We do have cookies. And we've defined a number of extensions to 148 cookies to blunt some of their sharper edges: the "HttpOnly" 149 attribute, the "Secure" attribute, "SameSite", prefixes like 150 "__Host-" and "__Secure-", and so on. Isn't that the right way 151 forward? Shouldn't we just push developers towards these existing 152 flags on the existing state management primitive? 154 This document's underlying assumption is that it's going to be easier 155 to teach developers about a crazy new thing that's secure by default 156 than it would be to convince them to change their "Set-Cookie" 157 headers to include "__Host-name=value; HttpOnly; Secure; 158 SameSite=Lax; Path=/". A new thing resets expectations in a way that 159 vastly exceeds the impact of explanations about the the four 160 attributes that must be used, the one attribute that must not be 161 used, and the weird naming convention that ought to be adopted. 163 Moreover, it appears that we're collectively pretty bad at helping 164 developers understand the risks that might lead them to adopt The 165 Good Cookie Syntax(tm) above. Adoption of these features has been 166 quite slow. Based on data gathered from Chrome's telemetry in March, 167 2019, cookies are set as follows: 169 o ~6.8% of cookies are set with "HttpOnly". 171 o ~5.5% are set with "Secure". 173 o ~3.1% are set with "HttpOnly; Secure". 175 o ~0.06% are set with "SameSite=*; Secure". 177 o ~0.05% are set with "SameSite=*". 179 o ~0.03% are set with "HttpOnly; Secure; SameSite=*". 181 o ~0.006% are set with "SameSite=*; HttpOnly". 183 o ~0.005% are set with a "__Secure-" prefix. 185 o ~0.01% are set with a "__Host-" prefix. 187 In total: 189 o ~9.9% of cookies are marked as "HttpOnly". 191 o ~8.8% of cookies are marked as "Secure". 193 o ~0.1% of cookies are marked as "SameSite". 195 o ~84.2% of cookies use none of these features. 197 Given that "Secure" has been around since at least 1997 [RFC2109]; 198 ~9% adoption after more than two decades is not inspiring. 200 1.3. Examples 202 User agents can deliver HTTP state tokens to a server in a "Sec-Http- 203 State" header. For example, if a user agent has generated a token 204 bound to "https://example.com/" whose base64 encoding is 205 "hB2RfWaGyNk60sjHze5DzGYjSnL7tRF2HWSBx6J1o4k=" ([RFC4648], 206 Section 4), then it would generate the following header when 207 delivering the token along with requests to "https://example.com/": 209 Sec-Http-State: token=*hB2RfWa...GyNko4k=* 211 The server can control certain aspects of the token's delivery by 212 responding to requests with a "Sec-Http-State-Options" header: 214 Sec-Http-State-Options: max-age=3600, key=*b7kuUkp...lkRioC2=* 216 2. Conventions 218 2.1. Conformance 220 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 221 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 222 "OPTIONAL" in this document are to be interpreted as described in 223 BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all 224 capitals, as shown here. 226 2.2. Syntax 228 This document defines two Structured Headers 229 [I-D.ietf-httpbis-header-structure]. In doing so it relies upon the 230 Augmented Backus-Naur Form (ABNF) notation of [RFC5234] and the OWS 231 rule from [RFC7230]. 233 3. Infrastructure 235 3.1. HTTP State Tokens 237 An HTTP State Token holds a session identifier which allows a user 238 agent to maintain a stateful session with a specific origin, along 239 with associated metadata: 241 o "creation" is a timestamp representing the point in time when the 242 token was created. 244 o "delivery" specifies the initiating contexts from which the token 245 can be delivered. It is an enum of either "same-origin", "same- 246 site", or "cross-site". Unless otherwise specified, its value is 247 "same-site". 249 o "key" is a server-provided key which can be used to sign requests 250 with which the token is delivered. It is either null, or contains 251 up to 256-bits of binary data. Unless otherwise specified, its 252 value is null. 254 o "max-age" is a timestamp representing the token's lifetime in 255 seconds. Unless otherwise specified, HTTP State Tokens have a 256 3600 second (1 hour) "max-age". 258 o "value" is the token's value (surprising, right?). It contains up 259 to 256-bits of binary data. 261 An HTTP State Token is said to be "expired" if its "creation" 262 timestamp plus "max-age" seconds is in the past. 264 3.2. Requests and Responses 266 This document relies upon the definitions of "request" and "response" 267 found in [Fetch]. 269 A request's delivery scope can be obtained as follows: 271 1. Let "request-origin" be the request's "origin", and "target- 272 origin" be the request's "URL"'s "origin". 274 2. If the request was generated by the user agent as a response to 275 direct user interaction with the user agent (e.g. the user typed 276 an address into the agent's address bar, clicked a bookmark, or 277 etc.), return "same-origin". 279 3. If "request-origin" is same-origin with "target-origin", return 280 "same-origin". 282 4. If "request-origin"'s registrable domain is the same as "target- 283 origin"'s registrable domain, return "same-site". 285 5. Return "cross-site". 287 3.3. Token Storage 289 User agents MUST keep a list of all the unexpired HTTP State Tokens 290 which have been created. For the purposes of this document, we'll 291 assume that user agents keep this list in the form of a map whose 292 keys are origins, and whose values are HTTP State Tokens. 294 This map exposes three functions: 296 o An HTTP State Token can be stored for a given origin. If the 297 origin already exists in the map, the entry's value will be 298 overwritten with the new HTTP State Token. 300 o An origin's HTTP State Token can be retrieved. If the origin does 301 not exist in the map, "null" will be returned instead. 303 o An origin (along with its HTTP State Token) can be deleted from 304 the map. 306 The map is initially empty. 308 3.3.1. Generate an HTTP State Token for an origin 310 The user agent can generate a new HTTP State Token for an origin 311 using an algorithm equivalent to the following: 313 1. Delete "origin" from the user agent's token store. 315 2. Let "token" be a newly created HTTP State Token with its 316 properties set as follows: 318 * "creation": The current time. 320 * "delivery": "same-site" 322 * "key": null 324 * "max-age": 3600 326 * "value": 256 cryptographically random bits. 328 3. Store "token" in the user agent's token store for "origin". 330 4. If the user agent has defined a "NotifyHostHTTPStateReset()" 331 algorithm, call it with "origin". 333 5. Return "token". 335 Note: Step 4 recognizes that user agents may wish to notify an 336 origin's developers that HTTP state has been reset in order to enable 337 cleanup of state stored client-side. HTML might, for instance, wish 338 to post a message to a specially-named "BroadcastChannel" to enable 339 this kind of work. This could take something like the following 340 form: 342 let resetChannel = new BroadcastChannel('http-state-reset')); 343 resetChannel.onmessage = e => { /* Do exciting cleanup here. */ }; 345 4. Syntax 347 4.1. The 'Sec-Http-State' HTTP Header Field 349 The "Sec-Http-State" HTTP header field allows user agents to deliver 350 HTTP state tokens to servers as part of an HTTP request. 352 "Sec-Http-State" is a Structured Header 353 [I-D.ietf-httpbis-header-structure]. Its value MUST be a dictionary 354 ([I-D.ietf-httpbis-header-structure], Section 3.1). Its ABNF is: 356 Sec-Http-State = sh-dictionary 358 The dictionary MUST contain: 360 o Exactly one member whose key is "token", and whose value is binary 361 content ([I-D.ietf-httpbis-header-structure], Section 3.9) that 362 encodes the HTTP state token's value for the origin to which the 363 header is delivered. 365 If the "token" member contains more than 256 bits of binary 366 content, the member MUST be ignored. 368 The dictionary MAY contain: 370 o Exactly one member whose key is "sig", and whose value is binary 371 content ([I-D.ietf-httpbis-header-structure], Section 3.9) that 372 encodes a signature over the token and the request which contains 373 it, using a key previously delivered by the server. This 374 mechanism is described in Section 5.2. 376 If the "sig" member contains more than 256 bits of binary content, 377 the member MUST be ignored. 379 The "Sec-Http-State" header is parsed per the algorithm in 380 Section 4.2 of [I-D.ietf-httpbis-header-structure]. Servers MUST 381 ignore the header if parsing fails, or if the parsed header does not 382 contain a member whose key is "token". 384 User agents will attach a "Sec-Http-State" header to outgoing 385 requests according to the processing rules described in Section 5. 387 4.2. The 'Sec-Http-State-Options' HTTP Header Field 389 The "Sec-Http-State-Options" HTTP header field allows servers to 390 deliver configuration information to user agents as part of an HTTP 391 response. 393 "Sec-Http-State-Options" is a Structured Header 394 [I-D.ietf-httpbis-header-structure]. Its value MUST be a dictionary 395 ([I-D.ietf-httpbis-header-structure], Section 3.1). Its ABNF is: 397 Sec-Http-State-Options = sh-dictionary 399 The "Sec-Http-State-Options" header is parsed per the algorithm in 400 Section 4.2 of [I-D.ietf-httpbis-header-structure]. User agents MUST 401 ignore the header if parsing fails. 403 The dictionary MAY contain: 405 o Exactly one member whose key is "key", and whose value is binary 406 content ([I-D.ietf-httpbis-header-structure], Section 3.10) that 407 encodes an key which can be used to generate a signature over 408 outgoing requests. 410 o Exactly one member whose key is "delivery", and whose value is one 411 of the following tokens ([I-D.ietf-httpbis-header-structure], 412 Section 3.9): "same-origin", "same-site", or "cross-site". 414 If the "delivery" member contains an unknown identifier, the 415 member MUST be ignored. 417 o Exactly one member whose key is "max-age", and whose value is an 418 integer ([I-D.ietf-httpbis-header-structure], Section 3.6) 419 representing the server's desired lifetime for its HTTP State 420 Token. 422 If the "max-age" member contains anything other than a positive 423 integer, the member MUST be ignored. 425 User agents will process the "Sec-Http-State-Options" header on 426 incoming responses according to the processing rules described in 427 Section 6. 429 4.2.1. Examples 431 4.2.1.1. Cross-Site Delivery 433 Some servers will require access to their tokens from cross-site 434 contexts (perhaps to support authenticated activity or single-sign 435 on, etc). These servers can request a "cross-site" delivery option 436 by delivering the following header: 438 Sec-Http-State-Options: delivery=cross-site, ... 440 4.2.1.2. Token Lifetime 442 Other servers might want their sessions to persist for more than an 443 hour. These servers can request a more reasonable token lifetime 444 lifetime by by delivering the following header: 446 Sec-Http-State-Options: max-age=2592000, ... 448 Servers may also wish to explicitly trigger the token's expiration 449 (upon signout, for instance). Setting a "max-age" of "0" does the 450 trick: 452 Sec-Http-State-Options: max-age=0, ... 454 4.2.1.3. Token Provenance 456 For some servers, the client-generated token will be enough to 457 maintain state. They can treat it as an opaque session identifier, 458 and bind the user's state to it server-side. Other servers will 459 require additional assurance that they can trust the token's 460 provenance. To that end, servers can generate a unique key, 461 associate it with the session identifier on the server, and deliver 462 it to the client via an HTTP response header: 464 Sec-Http-State-Options: key=*ZH0GxtBMWA...nJudhZ8dtz*, ... 466 Clients will store that key, and use it to generate a signature over 467 some set of data that mitigates the risk of token capture: 469 Sec-HTTP-State: 470 token=*J6BRKa...MonM*, 471 sig=*(HMAC-SHA265(key, token+metadata))* 473 Note: This part in particular is not fully baked, and we need to do 474 some more work to flesh out the threat model (see also Token 475 Binding). Look at it as an area to explore, not a solidly thought- 476 out solution. 478 5. Delivering HTTP State Tokens 480 User agents deliver HTTP state tokens to servers by appending a "Sec- 481 Http-State" header field to outgoing requests. 483 This specification provides algorithms which are called at the 484 appropriate points in [Fetch] in order to attach "Sec-Http-State" 485 headers to outgoing requests, and to ensure that "Sec-Http-State- 486 Options" headers are correctly processed. 488 5.1. Attach HTTP State Tokens to a request 490 The user agent can attach HTTP State Tokens to a given request using 491 an algorithm equivalent to the following. This algorithm is intended 492 to execute as the request is being sent out over the network (after 493 Service Worker processing), perhaps after the "Cookie" header is 494 handled in step 5.17.1 of Section 4.5 of [Fetch], describing the 495 "HTTP-network-or-cache fetch" algorithm: 497 1. If the user agent is configured to suppress explicit identifiers 498 for the request, or if the request's URL is not _a priori_ 499 authenticated [Mixed-Content], then skip the remaining steps in 500 this algorithm, and return without modifying the request. 502 2. Let "target-origin" be the origin of "request"'s current URL. 504 3. Let "request-token" be the result of retrieving origin's token 505 from the user agent's token store, or "null" if no such token 506 exists. 508 4. If "request-token" is expired, clear the user agent's token 509 store for "target-origin", and set "request-token" to "null". 511 5. If "request-token" is "null", then: 513 1. If "request"'s delivery scope is "cross-site", return 514 without modifying the request. 516 Note: As the default "delivery" for HTTP State Tokens is 517 "same-site", we return early rather than generating a token 518 for a cross-site request. 520 2. Set "request-token" to the result of generating an HTTP 521 State Token for "target-origin", as defined in 522 Section 3.3.1. 524 6. Return without modifying the request if either of the following 525 statements are true: 527 * "request-token"'s "delivery" is "same-origin", and 528 "request"'s delivery scope is not "same-origin". 530 * "request-token"'s "delivery" is "same-site", and "request"'s 531 delivery scope is neither "same-origin" nor "same-site". 533 7. Let "serialized-value" be the base64 encoding ([RFC4648], 534 Section 4) of "request-token"'s value. 536 8. Insert a member into "header-value" whose key is "token" and 537 whose value is "serialized-value". 539 9. If "request-token"'s "key" is not null, then insert a member 540 into "header-value" whose key is "sig", and whose value is the 541 result of executing Section 5.2 on request, "serialized-value", 542 and "request-token"'s "key". 544 10. Append a header to "request"'s header list whose name is "Sec- 545 Http-State", and whose value is the result of serializing 546 "header-value" ([I-D.ietf-httpbis-header-structure], 547 Section 4.1). 549 5.2. Generate a request's signature 551 If the origin server provides a "key", the user agent will use it to 552 sign any outgoing requests which target that origin and include an 553 HTTP State Token. Note that the signature is produced before adding 554 the "Sec-Http-State" header to the request. 556 Given a request, a base64-encoded token value, and a key: 558 1. Let "cbor-request" be the result of building a CBOR 559 representation [RFC7409] of the given request, as specified in 560 the first element of the array described in Section 3.2 of 561 [I-D.yasskin-http-origin-signed-responses]. 563 2. Add an item to "cbor-request" which maps the byte string ':token' 564 to the byte string containing the given base64-encoded token 565 value. 567 3. Return the result of computing HMAC-SHA256 [RFC2104] over the 568 canonical CBOR serialization of "cbor-request" (Section 3.4 of 569 [I-D.yasskin-http-origin-signed-responses]), using the given 570 "key". 572 5.2.1. Example 574 The following request: 576 GET / HTTP/1.1 577 Host: example.com 578 Accept: */* 580 results in the following CBOR representation (represented using the 581 extended diagnostic notation from Appendix G of 582 [I-D.ietf-cbor-cddl]): 584 { 585 ':method': 'GET', 586 ':token': 'hB2RfWaGyNk60sjHze5DzGYjSnL7tRF2HWSBx6J1o4k=' 587 ':url': 'https://example.com/', 588 'accept': '*/*', 589 } 591 6. Configuring HTTP State Tokens 593 Servers configure the HTTP State Token representing a given users' 594 state by appending a "Sec-Http-State-Options" header field to 595 outgoing responses. 597 User agents MUST process this header on a given response as per the 598 following algorithm, which is intended to be called after the "Set- 599 Cookie" header is handled in step 11.4 of Section 4.6 of [Fetch], 600 which defines the "HTTP-network fetch" algorithm. 602 1. Let "response-origin" be the origin of response's URL. 604 2. If the response's URL is not _a priori_ authenticated 605 [Mixed-Content], return without altering "response-origin"'s HTTP 606 State Token. 608 3. Let "token" be the result of retrieving "response-origin"'s token 609 from the user agent's token store, or "null" if no such token 610 exists. 612 4. If "token" is expired, clear the user agent's token store for 613 "response-origin", and set "token" to "null". 615 5. If "token" is "null", then: 617 1. If "request"'s delivery scope is "cross-site", return without 618 modifying the request. 620 Note: As the default "delivery" for HTTP State Tokens is 621 "same-site", we return early rather than generating a token 622 for a cross-site request. 624 2. Set "token" to the result of generating an HTTP State Token 625 for "target-origin", as defined in Section 3.3.1. 627 6. If the response's header list contains "Sec-Http-State-Options", 628 then: 630 1. Let "header" be the result of getting response's "Sec-Http- 631 State-Options" header, and parsing parsing it per the 632 algorithm in Section 4.2 of 633 [I-D.ietf-httpbis-header-structure]. 635 2. Return without altering "response-origin"'s HTTP State Token 636 if any of the following conditions hold: 638 + Parsing the header results in failure. 640 + "header" has a member named "key" whose value is not a 641 byte sequence (Section 3.10 of 642 [I-D.ietf-httpbis-header-structure]) 644 + "header" has a member named "delivery" whose value is not 645 one of the following tokens (Section 3.9 of 646 [I-D.ietf-httpbis-header-structure]): "same-origin", 647 "same-site", and "cross-site". 649 + "header" has a member named "max-age" whose value is not a 650 positive integer (Section 3.6 of 651 [I-D.ietf-httpbis-header-structure]). 653 3. If "header" has a member named "key", set "token"'s "key" to 654 the member's value. 656 4. If "header" has a member named "delivery", set "token"'s 657 "delivery" to the member's value. 659 5. If "header" has a member named "max-age": 661 1. If the member's value is "0", generate a new HTTP State 662 Token for "response-origin" as defined in Section 3.3.1. 664 Otherwise, set "token"'s "max-age" to the member's value. 666 Note that "max-age" is processed last, meaning that any other 667 options specified alongside "max-age=0" will be de facto 668 ignored as a new token is generated, replacing the old. 670 7. Security and Privacy Considerations 672 HTTP State Tokens aim to mitigate some of the security and privacy 673 drawbacks that decades of implementation experience with cookies have 674 laid bare. It would be worthwhile to skim through the privacy 675 considerations (Section 7 of [RFC6265]) and security considerations 676 (Section 8 of [RFC6265]) of that existing state management mechanism, 677 as it forms a foundation upon which this document builds. 679 7.1. Confidentiality and Integrity 681 HTTP State Tokens improve upon cookies' weak confidentiality/ 682 integrity guarantees (see Sections 8.3, 8.5, 8.6, and 8.7 of 683 [RFC6265]) in several ways: 685 1. User agents MUST require secure channels (such as TLS) for 686 delivery and configuration of HTTP State Tokens. User agents 687 cannot be induced to deliver an origin's tokens across channels 688 visible to (and modifiable by) network attackers, nor can an 689 attack on DNS cause tokens to be revealed (as any server to which 690 the user could be directed will also need to authenticate itself, 691 which is presumably difficult). 693 2. HTTP State Tokens are mapped to origins, matching developers 694 expectations for client-side data generally. This ensures that 695 tokens are isolated by host and port: code running on 696 "https://bar.example.com/" cannot alter state on 697 "https://foo.example.com/" without the latter's cooperation, and 698 that the same applies to "https://example.com:8000/" and 699 "https://example.com:80/". 701 Note that this origin binding means that there are no path 702 restrictions for tokens. Servers relying upon these tokens for 703 state management SHOULD NOT run mutually distrusting services on 704 different paths of the same origin. 706 3. User agents MUST NOT expose HTTP State Tokens to non-HTTP APIs 707 which are web-accessible, thereby reducing the risk of accidental 708 exposure via cross-site scripting attack. 710 Further, the "Sec-" prefix on both "Sec-HTTP-State" and "Sec- 711 HTTP-State-Options" ensures that both are considered "forbidden 712 header names" by [Fetch]. The latter should also be treated as a 713 "forbidden response header". 715 7.2. Signed Sessions 717 HTTP State Tokens embrace the session identifier pattern discussed in 718 Section 8.4 of [RFC6265] by requiring that the client control the 719 token's value, setting it to a fixed-length, random byte sequence. 720 The client's control mitigates the risk of sensitive information 721 being stored in the token directly, and the token's length makes it 722 unlikely to be easily guessed. 724 Some servers will be interested in proving the token's provenance 725 over time, which they do today by storing cookies with signed values. 726 Since storing a signed value directly is impossible in a client- 727 controlled world, servers can instead store a "key", which is used to 728 sign outgoing requests. Since this key is never exposed directly to 729 the web, it provides a reasonable guarantee of client stability over 730 time which a server can rely upon when making risk judgements. 732 7.3. User Control 734 User agents MUST provide users with the ability to control the 735 creation and distribution of HTTP State Tokens, just as they do for 736 cookies today. This certainly means providing controls over first- 737 vs third-party distribution, control over the origins which can store 738 state, control over the state presented to origins, visibility into 739 the state of the user agent's token store, and etc. 741 Further, this document grants user agents wide latitude to experiment 742 with various distribution policies and limitations. The capabilities 743 offered by "delivery" and "max-age" should be considered upper bounds 744 on distribution, within which user agents are free to roam. 746 7.4. Lifetime 748 By default, HTTP State Tokens live for an hour, which is a compromise 749 between the reasonable desire of servers to maintain state across a 750 given user's session, and the privacy risks associated with long- 751 lived tokens stored on a user's disk. 753 Servers that desire a longer session lifetime can explicitly request 754 an extension, which the browser can choose to act on. 756 7.5. Ambient Authority and Cross-Site Delivery 758 HTTP State Tokens, like cookies, provide a form of ambient authority 759 (see Section 8.2 of [RFC6265]). By default, this authority is 760 limited to requests initiated by same-site actors, which serves as a 761 reasonable mitigation against some classes of attack (e.g. 763 "https://evil.com/" making authenticated requests to 764 "https://example.com/"). 766 Servers that desire to interact in an authenticated manner in cross- 767 site contexts are required to opt-into doing so by delivering an 768 appropriate "delivery" value in a "Sec-HTTP-State-Options" response 769 header. Servers which choose to do so SHOULD take reasonable 770 precautions, implementing CSRF tokens for sensitive actions, and 771 taking stock of the context from which a given request is initiated 772 (by examining incoming "Referrer", "Origin", and "Sec-Fetch-Site" 773 headers). 775 Further, tokens can only be created in same-origin or same-site 776 contexts, which means that cross-site identifier would only be 777 available after the relevant origin was visited in a same-site 778 context, and explicitly declared its tokens as being deliverable 779 cross-site (at which point the user agent is empowered to make some 780 decisions about how to handle that declaration). 782 8. IANA Considerations 784 8.1. Header Field Registry 786 This document registers the "Sec-Http-State" and "Sec-Http-State- 787 Options" header fields in the "Permanent Message Header Field Names" 788 registry located at https://www.iana.org/assignments/message-headers 789 [1]. 791 8.1.1. Sec-Http-State Header Field 793 Header field name: Sec-Http-State 795 Applicable protocol: http 797 Status: experimental 799 Author/Change controller: IETF 801 Specification document(s): This document (see Section 4.1) 803 Related information: (empty) 805 8.1.2. Sec-Http-State-Options Header Field 807 Header field name: Sec-Http-State-Options 809 Applicable protocol: http 810 Status: experimental 812 Author/Change controller: IETF 814 Specification document(s): This document (see Section 4.2) 816 Related information: (empty) 818 9. References 820 9.1. Normative References 822 [Fetch] van Kesteren, A., "Fetch", n.d., 823 . 825 [I-D.ietf-httpbis-header-structure] 826 Nottingham, M. and P. Kamp, "Structured Headers for HTTP", 827 draft-ietf-httpbis-header-structure-09 (work in progress), 828 December 2018. 830 [I-D.yasskin-http-origin-signed-responses] 831 Yasskin, J., "Signed HTTP Exchanges", draft-yasskin-http- 832 origin-signed-responses-05 (work in progress), January 833 2019. 835 [Mixed-Content] 836 West, M., "Mixed Content", n.d., 837 . 839 [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- 840 Hashing for Message Authentication", RFC 2104, 841 DOI 10.17487/RFC2104, February 1997, 842 . 844 [RFC2109] Kristol, D. and L. Montulli, "HTTP State Management 845 Mechanism", RFC 2109, DOI 10.17487/RFC2109, February 1997, 846 . 848 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 849 Requirement Levels", BCP 14, RFC 2119, 850 DOI 10.17487/RFC2119, March 1997, 851 . 853 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 854 Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, 855 . 857 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 858 Specifications: ABNF", STD 68, RFC 5234, 859 DOI 10.17487/RFC5234, January 2008, 860 . 862 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 863 Protocol (HTTP/1.1): Message Syntax and Routing", 864 RFC 7230, DOI 10.17487/RFC7230, June 2014, 865 . 867 [RFC7409] Haleplidis, E. and J. Halpern, "Forwarding and Control 868 Element Separation (ForCES) Packet Parallelization", 869 RFC 7409, DOI 10.17487/RFC7409, November 2014, 870 . 872 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 873 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 874 May 2017, . 876 9.2. Informative References 878 [I-D.abarth-cake] 879 Barth, A., "Origin Cookies", draft-abarth-cake-01 (work in 880 progress), March 2011. 882 [I-D.ietf-cbor-cddl] 883 Birkholz, H., Vigano, C., and C. Bormann, "Concise data 884 definition language (CDDL): a notational convention to 885 express CBOR and JSON data structures", draft-ietf-cbor- 886 cddl-08 (work in progress), March 2019. 888 [RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265, 889 DOI 10.17487/RFC6265, April 2011, 890 . 892 9.3. URIs 894 [1] https://www.iana.org/assignments/message-headers 896 Appendix A. Acknowledgements 898 This document owes much to Adam Barth's [I-D.abarth-cake] and 899 [RFC6265]. 901 Appendix B. Changes 903 _RFC Editor: Please remove this section before publication._ 905 B.1. Since the beginning of time 907 o This document was created. 909 Author's Address 911 Mike West 912 Google 914 Email: mkwst@google.com 915 URI: https://www.mikewest.org/