Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define Sec-Fetch-Frame-Ancestors. #89

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 94 additions & 17 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Abstract:
enough information to make <i lang="la">a priori</i> decisions about whether or not to service
a request based on the way it was made, and the context in which it will be used.
Markup Shorthands: markdown yes
Issue Tracking: Github https://github.com/w3c/webappsec-fetch-metadata/issues/new
!Participate: <a href="https://github.com/w3c/webappsec-fetch-metadata/issues/new">File an issue</a> (<a href="https://github.com/w3c/webappsec-fetch-metadata/issues">open issues</a>)
!Tests: <a href=https://github.com/web-platform-tests/wpt/tree/master/fetch/sec-metadata>web-platform-tests fetch/sec-metadata/</a>
Version History: https://github.com/w3c/webappsec-fetch-metadata/commits/main/index.bs
Expand Down Expand Up @@ -87,11 +88,12 @@ proxies, CDNs, etc) if desired.
Examples {#examples}
--------------------

A request generated by a <{picture}> element would result in a request containing the following
A request generated by a <{picture}> element might result in a request containing the following
HTTP request headers:

```
Sec-Fetch-Dest: image
Sec-Fetch-Frame-Ancestors: cross-site
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: cross-site
```
Expand Down Expand Up @@ -165,6 +167,69 @@ To <dfn abstract-op lt="set-dest">set the `Sec-Fetch-Dest` header</dfn> for a [=
</div>


The `Sec-Fetch-Frame-Ancestors` HTTP Request Header {#sec-fetch-frame-ancestors-header}
---------------------------------------------------------------------------------------

The <dfn http-header export>`Sec-Fetch-Frame-Ancestors`</dfn> HTTP request header exposes the
relationship between a [=request=]'s initiator's origin, its target origin, and the origins of
the chain of ancestor documents that embed the initiator. It is a [=Structured Header=] whose
value is a [=structured header/token=]. [[!I-D.ietf-httpbis-header-structure]] Its ABNF is:

```
Sec-Fetch-Frame-Ancestors = sh-token
```

Valid `Sec-Fetch-Frame-Ancestors` values include "`cross-site`", "`same-origin`", "`same-site`",
and "`none`". In order to support forward-compatibility with as-yet-unknown request types,
servers SHOULD ignore this header if it contains an invalid value.

Note: This header is delivered for all requests other than top-level navigations. Those are
identifiable by examining the &#96;<a http-header>`Sec-Fetch-Dest`</a>&#96;header's value, so we
can safely omit this header as it would be fully redundant in that case.

<div algorithm="set `Sec-Fetch-Frame-Ancestors`">
To <dfn abstract-op lt="set-frame-ancestors">set the `Sec-Fetch-Frame-Ancestors` header</dfn> for a [=request=] |r|:

<ol class="algorithm">
1. Assert: |r|'s [=request/url=] is a [=potentially trustworthy URL=].

2. If |r|'s [=request/destination=] is "`document`", return.

3. Let |header| be a [=Structured Header=] whose value is a [=structured header/token=].

3. Set |header|'s value to "`same-origin`"..

4. Let |site| be the result of <a abstract-op lt="determine-site">determining |r|'s site value</a>.

5. Switch on |site|, and run the associated steps:

: "`none`"
:: Set |header|'s value to "`none`".
: "`cross-site`"
:: Set |header|'s value to "`cross-site`".
: "`same-site`"
: "`same-origin`"
:: For each |ancestor| in |r|'s [=request/client=]'s [=environment settings object/global object=]'s
[=associated `Document`=]'s [=Document/inclusive ancestor navigables=]:

1. Let |ancestor origin| be |ancestor|'s [=navigable/active document=]'s [=Document/origin=].

2. If |ancestor origin| is not [=same site=] with |r|'s [=request/origin=], set |header|'s value
to "`cross-site`", and [=iteration/break=].

3. If |ancestor origin| is not [=same origin=] with |r|'s [=request/origin=], set |header|'s value
to "`same-site`", and [=iteration/break=].

Note: We're relying on the fact that <a abstract-op lt='determine-site'>determine a request's site value</a> walks the
redirect chain, and the output can be "`same-site`" or "`same-origin`" only in cases where the
request's client is same-origin or same-site with each item in the chain. The only things we
need to compare, then, are the ancestor chain and the request's request/origin.

6. [=header list/Set a structured field value=]
&#96;<a http-header>`Sec-Fetch-Frame-Ancestors`</a>&#96;/|header| in |r|'s [=request/header list=].
</ol>
</div>


The `Sec-Fetch-Mode` HTTP Request Header {#sec-fetch-mode-header}
-----------------------------------------------------------------
Expand Down Expand Up @@ -212,33 +277,43 @@ Valid `Sec-Fetch-Site` values include "`cross-site`", "`same-origin`", "`same-si
In order to support forward-compatibility with as-yet-unknown request types, servers SHOULD ignore
this header if it contains an invalid value.

<div algorithm="set `Sec-Fetch-Site`">
To <dfn abstract-op lt="set-site">set the `Sec-Fetch-Site` header</dfn> for a [=request=] |r|:
<div algorithm="determine request's site">
To <dfn abstract-op lt="determine-site">determine a request's site value</dfn> for a [=request=] |r|:

<ol class="algorithm">
1. Assert: |r|'s [=request/url=] is a [=potentially trustworthy URL=].

2. Let |header| be a [=Structured Header=] whose value is a [=structured header/token=].

3. Set |header|'s value to `same-origin`.
1. Let |result| be "`same-origin`".

4. If |r| is a [=navigation request=] that was explicitly caused by a user's interaction with
2. If |r| is a [=navigation request=] that was explicitly caused by a user's interaction with
the user agent (by typing an address into the user agent directly, for example, or by
clicking a bookmark, etc.), then set |header|'s value to `none`.
clicking a bookmark, etc.), then set |result| to "`none`".

Note: See [[#directly-user-initiated]] for more detail on this somewhat poorly-defined step.

5. If |header|'s value is not `none`, then for each |url| in |r|'s [=request/url list=]:
3. If |result| is not "`none`", then for each |url| in |r|'s [=request/url list=]:

1. If |url| is [=same origin=] with |r|'s [=request/origin=], [=iteration/continue=].

2. Set |header|'s value to `cross-site`.
2. Set |result| to "`cross-site`".

3. If |r|'s [=request/origin=] is not [=same site=] with |url|'s [=url/origin=], then [=iteration/break=].

4. Set |header|'s value to `same-site`.
4. Set |result| to "`same-site`".

6. [=header list/Set a structured field value=]
4. Return |result|.
</ol>
</div>

<div algorithm="set `Sec-Fetch-Site`">
To <dfn abstract-op lt="set-site">set the `Sec-Fetch-Site` header</dfn> for a [=request=] |r|:

<ol class="algorithm">
1. Assert: |r|'s [=request/url=] is a [=potentially trustworthy URL=].

2. Let |header| be a [=Structured Header=] whose value is a [=structured header/token=].

3. Set |header|'s value to the result of <a abstract-op lt="determine-site">determining |r|'s site value</a>.

4. [=header list/Set a structured field value=]
&#96;<a http-header>`Sec-Fetch-Site`</a>&#96;/|header| in |r|'s [=request/header list=].
</ol>
</div>
Expand Down Expand Up @@ -298,11 +373,13 @@ To <dfn abstract-op export>append the Fetch metadata headers for a request</dfn>

2. <a abstract-op lt='set-dest'>Set the `Sec-Fetch-Dest` header</a> for |r|.

3. <a abstract-op lt='set-mode'>Set the `Sec-Fetch-Mode` header</a> for |r|.
3. <a abstract-op lt='set-frame-ancestors'>Set the `Sec-Fetch-Frame-Ancestors` header</a> for |r|.

4. <a abstract-op lt='set-mode'>Set the `Sec-Fetch-Mode` header</a> for |r|.

4. <a abstract-op lt='set-site'>Set the `Sec-Fetch-Site` header</a> for |r|.
5. <a abstract-op lt='set-site'>Set the `Sec-Fetch-Site` header</a> for |r|.

5. <a abstract-op lt='set-user'>Set the `Sec-Fetch-User` header</a> for |r|.
6. <a abstract-op lt='set-user'>Set the `Sec-Fetch-User` header</a> for |r|.
</ol>
</div>

Expand Down
Loading