├── .gitignore
├── w3c.json
├── README.md
├── LICENSE.md
├── CODE_OF_CONDUCT.md
├── .github
└── workflows
│ └── build-validate-publish.yml
├── CONTRIBUTING.md
├── index.bs
└── fpwd.html
/.gitignore:
--------------------------------------------------------------------------------
1 | index.html
2 |
--------------------------------------------------------------------------------
/w3c.json:
--------------------------------------------------------------------------------
1 | {
2 | "group": [49309]
3 | , "contacts": ["wseltzer","weiler"]
4 | , "repo-type": "note"
5 | }
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Post-Spectre Web Development
2 |
3 | Sketching a threat model and concrete examples of mitigation.
4 |
5 |
2 | Title: Post-Spectre Web Development 3 | Shortname: post-spectre-webdev 4 | Level: none 5 | Status: ED 6 | Group: WebAppSec 7 | ED: https://w3c.github.io/webappsec-post-spectre-webdev/ 8 | TR: https://www.w3.org/TR/post-spectre-webdev/ 9 | Previous Version: from biblio 10 | Editor: Mike West, Google, mkwst@google.com, w3cid 56384 11 | Abstract: 12 | Post-Spectre, we need to adopt some new strategies for safe and secure web development. This 13 | document outlines a threat model we can share, and a set of mitigation recommendations. 14 | 15 | **TL;DR**: Your data must not unexpectedly enter an attacker's process. 16 | Boilerplate: omit conformance 17 | Markup Shorthands: css off, markdown on 18 |19 |
20 | urlPrefix: https://html.spec.whatwg.org/; spec: HTML; 21 | type: dfn 22 | text: origin; url: multipage/origin.html#concept-origin 23 | text: cross-origin opener policy; url: multipage/origin.html#cross-origin-opener-policies 24 | text: cross-origin embedder policy; url: multipage/origin.html#coep 25 | type: http-header 26 | text: cross-origin-opener-policy; url: multipage/origin.html#cross-origin-opener-policies 27 | text: x-frame-options; url: multipage/browsing-the-web.html#the-x-frame-options-header 28 | urlPrefix: https://fetch.spec.whatwg.org/; spec: FETCH; type: dfn 29 | text: cross-origin resource policy; url: #http-cross-origin-resource-policy 30 | text: cross-origin read blocking; url: #corb 31 | urlPrefix: https://tc39.es/ecma262/; spec: ECMA262; type: interface 32 | text: SharedArrayBuffer; url: #sec-sharedarraybuffer-objects 33 | urlPrefix: https://tools.ietf.org/html/rfc7231; spec: RFC7231; type: http-header 34 | text: Vary; url: #section-7.1.4 35 | urlPrefix: https://fetch.spec.whatwg.org/; spec: FETCH; type: http-header 36 | text: Origin; url: #origin-header 37 |38 |
39 | {
40 | "spectre": {
41 | "href": "https://ieeexplore.ieee.org/document/8835233",
42 | "title": "Spectre Attacks: Exploiting Speculative Execution",
43 | "publisher": "40th IEEE Symposium on Security and Privacy (S&P'19)",
44 | "date": "May 2019",
45 | "authors": [
46 | "Paul Kocher",
47 | "Jann Horn",
48 | "Anders Fogh",
49 | "Daniel Genkin",
50 | "Daniel Gruss",
51 | "Werner Haas",
52 | "Mike Hamburg",
53 | "Moritz Lipp",
54 | "Stefan Mangard",
55 | "Thomas Prescher",
56 | "Michael Schwarz",
57 | "Yuval Yarom"
58 | ]
59 | },
60 | "post-spectre-rethink": {
61 | "href": "https://chromium.googlesource.com/chromium/src/+/master/docs/security/side-channel-threat-model.md",
62 | "title": "Post-Spectre Threat Model Re-Think",
63 | "authors": [ "Chromium" ]
64 | },
65 | "site-isolation": {
66 | "href": "https://www.chromium.org/Home/chromium-security/site-isolation",
67 | "title": "Site Isolation",
68 | "authors": [ "Chromium" ]
69 | },
70 | "project-fission": {
71 | "href": "https://wiki.mozilla.org/Project_Fission",
72 | "title": "Project Fission",
73 | "authors": [ "Mozilla" ]
74 | },
75 | "resource-isolation-policy": {
76 | "href": "https://xsleaks.dev/docs/defenses/isolation-policies/resource-isolation/",
77 | "title": "Resource Isolation Policy",
78 | "authors": [ "XSLeaks Wiki" ]
79 | },
80 | "cross-origin-isolation-guide": {
81 | "href": "https://web.dev/cross-origin-isolation-guide/",
82 | "title": "A guide to enable cross-origin isolation",
83 | "authors": [ "Eiji Kitamura" ]
84 | },
85 | "coop-coep": {
86 | "href": "https://web.dev/coop-coep/",
87 | "title": "Making your website 'cross-origin isolated' using COOP and COEP",
88 | "authors": [ "Eiji Kitamura" ]
89 | },
90 | "coop-coep-explained": {
91 | "href": "https://docs.google.com/document/d/1zDlfvfTJ_9e8Jdc8ehuV4zMEu9ySMCiTGMS9y0GU92k/edit",
92 | "title": "COOP and COEP Explained",
93 | "authors": [ "Artur Janc", "Charlie Reis", "Anne van Kesteren" ],
94 | "date": "2020-01-03"
95 | },
96 | "application-principals": {
97 | "href": "https://noncombatant.org/application-principals/",
98 | "title": "Isolating Application-Defined Principals",
99 | "authors": [ "Chris Palmer" ],
100 | "date": "2018-06-19"
101 | },
102 | "long-term-mitigations": {
103 | "href": "https://docs.google.com/document/d/1dnUjxfGWnvhQEIyCZb0F2LmCZ9gio6ogu2rhMGqi6gY/edit",
104 | "title": "Long-Term Web Browser Mitigations for Spectre",
105 | "authors": [ "Charlie Reis" ],
106 | "date": "2019-03-04"
107 | },
108 | "spectre-shaped-web": {
109 | "href": "https://docs.google.com/presentation/d/1sadl7jTrBIECCanuqSrNndnDr82NGW1yyuXFT1Dc7SQ/edit#slide=id.p",
110 | "title": "A Spectre-shaped Web",
111 | "authors": [ "Anne van Kesteren" ],
112 | "date": "2019-04-16"
113 | },
114 | "spilling-the-beans": {
115 | "href": "https://www.arturjanc.com/cross-origin-infoleaks.pdf",
116 | "title": "How do we Stop Spilling The Beans Across Origins?",
117 | "authors": [ "Artur Janc", "Mike West" ],
118 | "date": "2018-05-16"
119 | },
120 | "cross-origin-embedder-policy": {
121 | "href": "https://wicg.github.io/cross-origin-embedder-policy/",
122 | "title": "Cross-Origin Embedder Policy",
123 | "authors": [ "Mike West" ],
124 | "date": "2020-09-29"
125 | },
126 | "cross-origin-opener-policy-explainer": {
127 | "href": "https://docs.google.com/document/d/1Ey3MXcLzwR1T7aarkpBXEwP7jKdd2NvQdgYvF8_8scI/edit",
128 | "title": "Cross-Origin-Opener-Policy Explainer",
129 | "authors": [ "Charlie Reis", "Camille Lamy" ],
130 | "date": "2020-05-24"
131 | },
132 | "safely-reviving-shared-memory": {
133 | "href": "https://hacks.mozilla.org/2020/07/safely-reviving-shared-memory/",
134 | "title": "Safely reviving shared memory",
135 | "authors": [ "Anne van Kesteren" ],
136 | "date": "2020-07-21"
137 | },
138 | "coi-threat-model": {
139 | "href": "https://arturjanc.com/coi-threat-model.pdf",
140 | "title": "Notes on the threat model of cross-origin isolation",
141 | "authors": [ "Artur Janc" ],
142 | "date": "2020-12"
143 | },
144 | "orb": {
145 | "href": "https://github.com/annevk/orb",
146 | "title": "Opaque Response Blocking (ORB, aka CORB++)",
147 | "authors": [ "Anne van Kesteren" ]
148 | },
149 | "oopif": {
150 | "href": "https://www.chromium.org/developers/design-documents/oop-iframes",
151 | "title": "Out-of-Process iframes (OOPIFs)",
152 | "authors": [ "Chromium" ]
153 | },
154 | "embedding-requires-opt-in": {
155 | "href": "https://github.com/mikewest/embedding-requires-opt-in",
156 | "title": "Embedding Should Require Explicit Opt-In",
157 | "authors": [ "Mike West" ]
158 | },
159 | "coop-by-default": {
160 | "href": "https://github.com/mikewest/coop-by-default",
161 | "title": "COOP By Default",
162 | "authors": [ "Mike West" ]
163 | }
164 | }
165 |
166 |
167 | Introduction {#intro}
168 | =====================
169 |
170 | In early 2018, Spectre made it clear that a foundational security boundary the web aimed to
171 | maintain was substantially less robust than expected. [[SPECTRE]] This revelation has pushed web
172 | browsers to shift their focus from the platform-level [=origin=] boundary to an OS-level
173 | process boundary. Chromium's threat model, for instance, now asserts that "active web content …
174 | will be able to read any and all data in the address space of the process that hosts it".
175 | [[POST-SPECTRE-RETHINK]] This shift in thinking imposes a shift in development practice, both
176 | for browser vendors, and for web developers. Browsers need to align the origin boundary with the
177 | process boundary through fundamental refactoring projects (for example, [[SITE-ISOLATION]] and
178 | [[PROJECT-FISSION]]). Moreover, browsers must provide web developers with tools to mitigate risk
179 | in the short term, and should push the platform towards safe default behaviors in the long term.
180 | The bad news is that this is going to be a lot of work, much of it falling on the shoulders of
181 | web developers. The good news is that a reasonable set of mitigation primitives exists today,
182 | ready and waiting for use.
183 |
184 | This document will summarize the threat model which the Web Application Security Working Group
185 | espouses, point to a set of mitigations which seem promising, and provide concrete recommendations
186 | for developers responsible for protecting users' data.
187 |
188 | Threat Model {#threat-model}
189 | ----------------------------
190 |
191 | Spectre-like side-channel attacks inexorably lead to a model in which active web content
192 | (JavaScript, WASM, probably CSS if we tried hard enough, and so on) can read any and all data which
193 | has entered the address space of the process which hosts it. While this has deep implications for
194 | user agent implementations' internal hardening strategies (stack canaries, ASLR, etc), here we'll
195 | remain focused on the core implication at the web platform level, which is both simple and profound:
196 | any data which flows into a process hosting a given origin is legible to that origin. We must design
197 | accordingly.
198 |
199 | In order to determine the scope of data that can be assumed accessible to an attacker, we must make
200 | a few assumptions about the normally-not-web-exposed process model which the user agent implements.
201 | The following seems like a good place to start:
202 |
203 | 1. User agents are capable of separating the execution of a web origin's code into a process
204 | distinct from the agent's core. This separation enables the agent itself to access local
205 | devices, fetch resources, broker cross-process communication, and so on, in a way which remains
206 | invisible to any process potentially hosting untrusted code.
207 |
208 | 2. User agents are able to make decisions about whether or not a given resource should be delivered
209 | to a process hosting a given origin based on characteristics of both the request and the
210 | response (headers, etc).
211 |
212 | 3. User agents can consistently separate top-level, cross-origin windows into distinct processes.
213 | They cannot consistently separate same-site or same-origin windows into distinct processes given
214 | the potential for synchronous access between the windows.
215 |
216 | 4. User agents cannot yet consistently separate framed origins into processes distinct from their
217 | embedders' origin.
218 |
219 | Note: Though some user agents support out-of-process frames [[OOPIF]], no agent supports it
220 | consistently across a broad range of devices and platforms. Ideally this will change over time,
221 | as the frame boundary *must* be one we can eventually consider robust.
222 |
223 | With this in mind, our general assumption will be that an origin gains access to any resource which
224 | it renders (including images, stylesheets, scripts, frames, etc). Likewise, embedded frames gain
225 | access to their ancestors' content.
226 |
227 | ISSUE: [[COI-THREAT-MODEL]] spells out more implications. Bring them in here for more nuance.
228 |
229 | TL;DR {#tldr}
230 | -------------
231 |
232 | 1. **Decide when (not!) to respond to requests** by examining incoming headers, paying special
233 | attention to the `Origin` header on the one hand, and various `Sec-Fetch-`
234 | prefixed headers on the other, as described in [[resource-isolation-policy]].
235 |
236 | 2. **Restrict attackers' ability to load your data as a subresource** by setting a
237 | [=cross-origin resource policy=] (CORP) of `same-origin` (opening up to `same-site`
238 | or `cross-origin` only when necessary).
239 |
240 | 3. **Restrict attackers' ability to frame your data as a document** by opt-ing into framing
241 | protections via `X-Frame-Options: SAMEORIGIN` or CSP's more granular [=frame-ancestors=]
242 | directive (`frame-ancestors 'self' https://trusted.embedder`, for example).
243 |
244 | 4. **Restrict attackers' ability to obtain a handle to your window** by setting a
245 | [=cross-origin opener policy=] (COOP). In the best case, you can default to a restrictive
246 | `same-origin` value, opening up to `same-origin-allow-popups` or `unsafe-none` only if
247 | necessary.
248 |
249 | 5. **Prevent MIME-type confusion attacks** and increase the robustness of passive defenses like
250 | [=cross-origin read blocking=] (CORB) /
251 | opaque response blocking ([[ORB]]) by setting
252 | correct `Content-Type` headers, and globally asserting `X-Content-Type-Options: nosniff`.
253 |
254 | ISSUE: Describe these mitigations in more depth, swiping liberally from
255 | Notes on the threat model of *cross-origin isolation*,
256 | Safely reviving shared memory, etc.
257 |
258 | Practical Examples {#examples}
259 | ==============================
260 |
261 | Subresources {#subresources}
262 | ----------------------------
263 |
264 | Resources which are intended to be loaded into documents should protect themselves from being used
265 | in unexpected ways. Before walking through strategies for specific kinds of resources, a few headers
266 | seem generally applicable:
267 |
268 | 1. Sites should use Fetch Metadata to make good decisions about when to serve resources, as
269 | described in [[resource-isolation-policy]]. In order to ensure that decision sticks, servers
270 | should explain its decision to the browser by sending a `Vary` header
271 | containing `Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User`. This ensures that
272 | the server has a chance to make different decisions for requests which will be *used*
273 | differently.
274 |
275 | 2. Subresources should opt-out of MIME type sniffing by sending an
276 | `X-Content-Type-Options` header with a value of `nosniff`. This increases the
277 | robustness of MIME-based checks like [=cross-origin read blocking=] (CORB) /
278 | opaque response blocking ([[ORB]]), and mitigates
279 | some well-known risks around type confusion for scripts.
280 |
281 | 3. Subresources are intended for inclusion in a given context, not as independently navigable
282 | documents. To mitigate the risk that navigation to a subresource causes script execution or
283 | opens an origin up to attack in some other way, servers can assert the following set of headers
284 | which collectively make it difficult to meaningfully abuse a subresource via navigation:
285 |
286 | * Using the `Content-Security-Policy` header's to assert the
287 | `sandbox` directive ensures that these resources remain inactive if navigated to
288 | directly as a top-level document. No scripts will execute, and the resource will be pushed
289 | into an [=opaque origin=].
290 |
291 | Note: Some servers deliver `Content-Disposition: attachment; filename=file.name` to obtain
292 | a similar effect. This was valuable to mitigate vulnerabilities in Flash, but the sandbox
293 | approach seems to more straightforwardly address the threats we care about today.
294 |
295 | * Asserting the `Cross-Origin-Opener-Policy` header with a value of
296 | `same-origin` prevents cross-origin documents from retaining a handle to the resource's
297 | window if it's opened in a popup.
298 |
299 | * The `X-Frame-Options` header with a value of `DENY` prevents the resource
300 | from being framed.
301 |
302 | Most subresources, then, should contain the following block of headers, which you'll see repeated a
303 | few times below:
304 |
305 | 306 | Content-Security-Policy: sandbox 307 | Cross-Origin-Opener-Policy: same-origin 308 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 309 | X-Content-Type-Options: nosniff 310 | X-Frame-Options: DENY 311 |312 | 313 | With these generic protections in mind, let's sift through a few scenarios to determine what headers 314 | a server would be well-served to assert: 315 | 316 | ### Static Subresources ### {#static-subresources} 317 | 318 | By their nature, static resources contain the same data no matter who requests them, and therefore 319 | cannot contain interesting information that an attacker couldn't otherwise obtain. There's no risk 320 | to making these resources widely available, and value in allowing embedders to robustly debug, so 321 | something like the following response headers could be appropriate: 322 | 323 |
324 | Access-Control-Allow-Origin: * 325 | Cross-Origin-Resource-Policy: cross-origin 326 | Timing-Allow-Origin: * 327 | Content-Security-Policy: sandbox 328 | Cross-Origin-Opener-Policy: same-origin 329 | X-Content-Type-Options: nosniff 330 | X-Frame-Options: DENY 331 |332 | 333 | Note: Purely static resources always respond with the same data, no matter the request. There's 334 | therefore little benefit to sending a `Vary` header: it can be safely omitted for these responses. 335 | 336 | CDNs are the canonical static resource distribution points, and many use the pattern above. Take 337 | a look at the following common resources' response headers for inspiration: 338 | 339 | * `https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js` 340 | * `https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js` 341 | * `https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js` 342 | * `https://ssl.google-analytics.com/ga.js` 343 | 344 | Similarly, application-specific static resource servers are a good place to look for this practice. Consider: 345 | 346 | * `https://static.xx.fbcdn.net/rsrc.php/v3/y2/r/zVvRrO8pOtu.png` 347 | * `https://www.gstatic.com/images/branding/googlelogo/svg/googlelogo_clr_74x24px.svg` 348 | 349 | ### Dynamic Subresources ### {#dynamic-subresources} 350 | 351 | Subresources that contain data personalized to a given user are juicy targets for attackers, and 352 | must be defended by ensuring that they're loaded only in ways that are appropriate for the data 353 | in question. A few cases are well worth considering: 354 | 355 | 1. Application-internal resources (private API endpoints, avatar images, uploaded data, etc.) 356 | should not be available to any cross-origin requestor. These resources should be restricted to 357 | usage as a subresource in same-origin contexts by sending a 358 | `Cross-Origin-Resource-Policy` header with a value of `same-origin`: 359 | 360 |
361 | Cross-Origin-Resource-Policy: same-origin 362 | Content-Security-Policy: sandbox 363 | Cross-Origin-Opener-Policy: same-origin 364 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 365 | X-Content-Type-Options: nosniff 366 | X-Frame-Options: DENY 367 |368 | 369 | This header will prevent cross-origin attackers from loading the resource as a response to a 370 | `no-cors` request. 371 | 372 | For example, examine the headers returned when requesting endpoints like the following: 373 | 374 | * `https://myaccount.google.com/_/AccountSettingsUi/browserinfo` 375 | * `https://twitter.com/i/api/1.1/branch/init.json` 376 | * `https://www.facebook.com/ajax/webstorage/process_keys/?state=0` 377 | 378 | 2. Personalized resources intended for cross-origin use (public API endpoints, etc) should 379 | carefully consider incoming requests' properties before responding. These endpoints can only 380 | safely be enabled by requiring CORS, and choosing the set of origins for which a given response 381 | can be exposed by setting the appropriate access-control headers, for example: 382 | 383 |
384 | Access-Control-Allow-Credentials: true 385 | Access-Control-Allow-Origin: https://trusted.example 386 | Access-Control-Allow-Methods: POST 387 | Access-Control-Allow-Headers: ... 388 | Access-Control-Allow-...: ... 389 | Cross-Origin-Resource-Policy: same-origin 390 | Content-Security-Policy: sandbox 391 | Cross-Origin-Opener-Policy: same-origin 392 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 393 | X-Content-Type-Options: nosniff 394 | X-Frame-Options: DENY 395 |396 | 397 | Note: The `Cross-Origin-Resource-Policy` header is only processed for requests that are _not_ 398 | using CORS for access control ("`no-cors` requests"). Sending 399 | `Cross-Origin-Resource-Policy: same-origin` is therefore not harmful, and works to ensure that 400 | `no-cors` usage isn't accidentally allowed. 401 | 402 | For example, examine the headers returned when requesting endpoints like the following: 403 | 404 | * `https://api.twitter.com/1.1/jot/client_event.json` 405 | * `https://play.google.com/log?format=json&hasfast=true` 406 | * `https://securepubads.g.doubleclick.net/pcs/view` 407 | * `https://c.amazon-adsystem.com/e/dtb/bid` 408 | 409 | 3. Personalized resources that are intended for cross-origin `no-cors` embedding, but which don't 410 | intend to be directly legible in that context (avatar images, authenticated media, etc). These 411 | should enable cross-origin embedding via `Cross-Origin-Resource-Policy`, but _not_ via CORS 412 | access control headers: 413 | 414 |
415 | Cross-Origin-Resource-Policy: cross-origin 416 | Content-Security-Policy: sandbox 417 | Cross-Origin-Opener-Policy: same-origin 418 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 419 | X-Content-Type-Options: nosniff 420 | X-Frame-Options: DENY 421 |422 | 423 |
455 | Cross-Origin-Opener-Policy: same-origin 456 | Cross-Origin-Resource-Policy: same-origin 457 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 458 | X-Content-Type-Options: nosniff 459 | X-Frame-Options: SAMEORIGIN 460 |461 | 462 | Note: Documents which need to make use of APIs that require full cross-origin isolation (such 463 | as {{SharedArrayBuffer}}), will also need to serve a `Cross-Origin-Embedder-Policy` header, as 464 | outlined in [[coop-coep]] and [[cross-origin-isolation-guide]]. 465 | 466 | Account settings pages, admin panels, and application-specific documents are all good examples of 467 | resources which would benefit from as much isolation as possible. For real-life examples, consider: 468 | 469 | * `https://myaccount.google.com/` 470 | 471 | 472 | ### Documents Expecting to Open Cross-Origin Windows ### {#documents-with-popups} 473 | 474 | Not every document that requires sign-in can be fully-isolated from the rest of the internet. It's 475 | often the case that partial isolation is a better fit. Consider sites that depend upon cross-origin 476 | windows for federated workflows involving payments or sign-in, for example. These pages would 477 | generally benefit from restricting attackers' ability to embed them, or obtain their window handle, 478 | but they can't easily lock themselves off from all such vectors via 479 | `Cross-Origin-Opener-Policy: same-origin` and `X-Frame-Options: DENY`. In these cases, something 480 | like the following set of response headers might be appropriate: 481 | 482 |
483 | Cross-Origin-Opener-Policy: same-origin-allow-popups 484 | Cross-Origin-Resource-Policy: same-origin 485 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 486 | X-Content-Type-Options: nosniff 487 | X-Frame-Options: SAMEORIGIN 488 |489 | 490 | The only difference between this case and the "Fully-Isolated" case above is the 491 | `Cross-Origin-Opener-Policy` value. `same-origin` will break the opener relationship between the 492 | document and any cross-origin window, regardless of who opened whom. 493 | `same-origin-allow-popups` will break cross-origin opener relationships initiated by a cross-origin 494 | document's use of `window.open()`, but will allow the asserting document to open cross-origin 495 | windows that retain an opener relationship. 496 | 497 | 498 | ### Documents Expecting Cross-Origin Openers ### {#documents-as-popups} 499 | 500 | Federated sign-in forms and payment providers are clear examples of documents which intend to be 501 | opened by cross-origin windows, and require that relationship to be maintained in order to 502 | facilitate communication via channels like {{Window/postMessage(message, options)}} or navigation. 503 | These documents cannot isolate themselves completely, but can prevent themselves from being embedded 504 | or fetched cross-origin. Three scenarios are worth considering: 505 | 506 | 1. Documents that only wish to be opened in cross-origin popups could loosen their cross-origin 507 | opener policy by serving the following headers: 508 | 509 |
510 | Cross-Origin-Resource-Policy: same-origin 511 | Cross-Origin-Opener-Policy: unsafe-none 512 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 513 | X-Content-Type-Options: nosniff 514 | X-Frame-Options: SAMEORIGIN 515 |516 | 517 | For example: 518 | 519 | * ISSUE: Find some links. 520 | 521 | 2. Documents that only wish to be framed in cross-origin contexts could loosen their framing 522 | protections by serving the following headers: 523 | 524 |
525 | Cross-Origin-Resource-Policy: same-origin 526 | Cross-Origin-Opener-Policy: same-origin 527 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 528 | X-Content-Type-Options: nosniff 529 | X-Frame-Options: ALLOWALL 530 |531 | 532 |
540 | Content-Security-Policy: frame-ancestors https://trusted1.example https://trusted2.example 541 |542 |
553 | Cross-Origin-Resource-Policy: same-origin 554 | Cross-Origin-Opener-Policy: unsafe-none 555 | Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User 556 | X-Content-Type-Options: nosniff 557 | X-Frame-Options: ALLOWALL 558 |559 | 560 | For example: 561 | 562 | * ISSUE: Find some links. 563 | 564 | Implementation Considerations {#considerations} 565 | =============================================== 566 | 567 | Explicitly Setting Headers with Default Values {#explicit-defaults} 568 | ------------------------------------------------------------------- 569 | 570 | Several recommendations above suggest that developers would be well-served to set headers like 571 | `X-Frame-Options: ALLOWALL` or `Cross-Origin-Opener-Policy: unsafe-none` on responses. These 572 | map to the web's status quo behavior, and seem therefore superfluous. Why should developers 573 | set them? 574 | 575 | The core reason is that these defaults are poor fits for today's threats, and we ought to be working 576 | to change them. Proposals like [[EMBEDDING-REQUIRES-OPT-IN]] and [[COOP-BY-DEFAULT]] suggest that 577 | we shift the web's defaults away from requiring developers to opt-into more secure behaviors by 578 | making them opt-out rather than opt-in. This would place the configuration cost on those developers 579 | whose projects require risky settings. 580 | 581 | This document recommends setting those less-secure header values explicitly, as that makes it more 582 | likely that we'll be able to shift the web's defaults in the future. 583 | 584 | Isolating Local-Scheme Frames {#local-scheme-frames} 585 | ---------------------------------------------------- 586 | 587 | Note that frames loaded from local schemes will generally inherit policies applied to the document 588 | which created them, and may end up in-process with that document if the stars align unfortunately. 589 | Developers are encouraged to explicitly shift these documents to opaque origins, either by using 590 | `data:` URLs directly, or by applying a <{iframe/sandbox}> attribute to frames created using 591 | `