| # Post-Spectre Web Development |
| |
| Contributors: Artur Janc, Camille Lamy, Charlie Reis, Jun Kokatsu, Mike West. |
| Patches and corrections welcome! |
| |
| Last Updated: Mar. 12th, 2021 |
| |
| *** note |
| **Note**: This document has been [adopted][cfc] by the W3C's Web Application Security |
| Working Group; [https://w3c.github.io/webappsec-post-spectre-webdev/][ED] is |
| proceeding under that group's aegis, and this document will redirect there |
| once the working group is satisfied with its recommendations. |
| *** |
| |
| [cfc]: https://lists.w3.org/Archives/Public/public-webappsec/2021Feb/0007.html |
| [ED]: https://w3c.github.io/webappsec-post-spectre-webdev/ |
| |
| [TOC] |
| |
| ## Introduction |
| |
| In early 2018, [Spectre][spectre] made it clear that a foundational security |
| boundary the web aimed to maintain was substantially less robust than expected. |
| This revelation has pushed web browsers to shift their focus from the |
| platform-level origin boundary to an OS-level process boundary. Chromium's |
| [threat model][post-spectre-rethink], for instance, now asserts that "active |
| web content … will be able to read any and all data in the address space of the |
| process that hosts it". This shift in thinking imposes a shift in development |
| practice, both for browser vendors, and for web developers. Browsers need to |
| align the origin boundary with the process boundary through fundamental |
| refactoring projects (for example, Chromium's [Site Isolation][site-isolation], |
| and Firefox's [Project Fission][project-fission]). Moreover, browsers must |
| provide web developers with tools to mitigate risk in the short term, and should |
| push the platform towards safe default behaviors in the long term. The bad news |
| is that this is going to be a lot of work, much of it falling on the shoulders |
| of web developers. The good news is that a reasonable set of mitigation |
| primitives exists today, ready and waiting for use. |
| |
| This document will point to a set of mitigations which seem promising, and |
| provide concrete recommendations for web developers responsible for protecting |
| users' data. |
| |
| [spectre]: https://spectreattack.com/ |
| [post-spectre-rethink]: https://chromium.googlesource.com/chromium/src/+/main/docs/security/side-channel-threat-model.md |
| [site-isolation]: https://www.chromium.org/Home/chromium-security/site-isolation |
| [project-fission]: https://wiki.mozilla.org/Project_Fission |
| |
| |
| ### Threat Model |
| |
| Spectre-like side-channel attacks inexorably lead to a model in which active web |
| content (JavaScript, WASM, probably CSS if we tried hard enough, and so on) can |
| read any and all data which has entered the address space of the process which |
| hosts it. While this has deep implications for user agent implementations' |
| internal hardening strategies (stack canaries, ASLR, etc), here we'll remain |
| focused on the core implication at the web platform level, which is both simple |
| and profound: any data which flows into a process hosting a given origin is |
| legible to that origin. We must design accordingly. |
| |
| In order to determine the scope of data that can be assumed accessible to an |
| attacker, we must make a few assumptions about the normally-not-web-exposed |
| process model which the user agent implements. The following seems like a good |
| place to start: |
| |
| 1. User agents are capable of separating the execution of a web origin's code |
| into a process distinct from the agent's core. This separation enables the |
| agent itself to access local devices, fetch resources, broker cross-process |
| communication, and so on, in a way which remains invisible to any process |
| potentially hosting untrusted code. |
| |
| 2. User agents are able to make decisions about whether or not a given resource |
| should be delivered to a process hosting a given origin based on |
| characteristics of both the request and the response (headers, etc). |
| |
| 3. User agents can consistently separate top-level, cross-origin windows into |
| distinct processes. They cannot consistently separate same-site or |
| same-origin windows into distinct processes given the potential for |
| synchronous access between the windows. |
| |
| 4. User agents cannot yet consistently separate framed origins into processes |
| distinct from their embedders' origin. |
| |
| Note: Though some user agents support [out-of-process frames][oopif], no |
| agent supports it consistently across a broad range of devices and |
| platforms. Ideally this will change over time, as the frame boundary *must* |
| be one we can eventually consider robust. |
| |
| With this in mind, our general assumption will be that an origin gains access to |
| any resource which it renders (including images, stylesheets, scripts, frames, |
| etc). Likewise, embedded frames gain access to their ancestors' content. |
| |
| This model is spelled out in more detail in both Chromium's |
| [Post-Spectre Threat Model Rethink][post-spectre-rethink], and in Artur Janc's |
| [Notes on the threat model of cross-origin isolation][coi-threat-model]. |
| |
| [oopif]: https://www.chromium.org/developers/design-documents/oop-iframes |
| [coi-threat-model]: https://arturjanc.com/coi-threat-model.pdf |
| |
| |
| ### Mitigation TL;DR |
| |
| 1. **Decide when (not!) to respond to requests** by examining incoming headers, |
| paying special attention to the `Origin` header on the one hand, and various |
| `Sec-Fetch-` prefixed headers on the other, as described in the article |
| [Protect your resources from web attacks with Fetch Metadata][fetch-metadata]. |
| |
| 2. **Restrict attackers' ability to load your data as a subresource** by |
| setting a [cross-origin resource policy][corp] (CORP) of `same-origin` |
| (opening up to `same-site` or `cross-origin` only when necessary). |
| |
| 3. **Restrict attackers' ability to frame your data as a document** by opt-ing |
| into framing protections via `X-Frame-Options: SAMEORIGIN` or CSP's more |
| granular `frame-ancestors` directive (`frame-ancestors 'self' |
| https://trusted.embedder`, for example). |
| |
| 4. **Restrict attackers' ability to obtain a handle to your window** by setting |
| a [cross-origin opener policy][coop] (COOP). In the best case, you can |
| default to a restrictive `same-origin` value, opening up to |
| `same-origin-allow-popups` or `unsafe-none` only if necessary. |
| |
| 5. **Prevent MIME-type confusion attacks** and increase the robustness of |
| passive defenses like [cross-origin read blocking][corb] (CORB) / |
| [opaque response blocking][orb] (ORB) by setting correct `Content-Type` |
| headers, and globally asserting `X-Content-Type-Options: nosniff`. |
| |
| [fetch-metadata]: https://web.dev/fetch-metadata/ |
| [corp]: https://resourcepolicy.fyi/ |
| [coop]: https://docs.google.com/document/d/1Ey3MXcLzwR1T7aarkpBXEwP7jKdd2NvQdgYvF8_8scI/edit |
| [corb]: https://chromium.googlesource.com/chromium/src/+/main/services/network/cross_origin_read_blocking_explainer.md |
| [orb]: https://github.com/annevk/orb |
| |
| |
| ## Practical Examples |
| |
| ### Subresources |
| |
| Resources which are intended to be loaded into documents should protect |
| themselves from being used in unexpected ways. Before walking through strategies |
| for specific kinds of resources, a few headers seem generally applicable: |
| |
| 1. Sites should use Fetch Metadata to make good decisions about |
| [when to serve resources][fetch-metadata]. In order to ensure that decision |
| sticks, servers should explain its decision to the browser by sending a |
| `Vary` header containing `Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site`. |
| This ensures that the server has a chance to make different decisions for |
| requests which will be *used* differently. |
| |
| 2. Subresources should opt-out of MIME type sniffing by sending an |
| `X-Content-Type-Options` header with a value of `nosniff`. This increases |
| the robustness of MIME-based checks like [cross-origin read blocking][corb] |
| and [opaque response blocking][orb], and mitigates some well-known risks |
| around type confusion for scripts. |
| |
| 3. Subresources are intended for inclusion in a given context, not as |
| independently navigable documents. To mitigate the risk that navigation to a |
| subresource causes script execution or opens an origin up to attack in some |
| other way, servers can assert the following set of headers which |
| collectively make it difficult to meaningfully abuse a subresource via |
| navigation: |
| |
| * Use the `Content-Security-Policy` header to assert the `sandbox` |
| directive. This ensures that these resources remain inactive if |
| navigated to directly as a top-level document. No scripts will execute, |
| and the resource will be pushed into an "opaque" origin. |
| |
| Note: Some servers deliver `Content-Disposition: attachment; |
| filename=file.name` to obtain a similar effect. This was valuable to |
| mitigate vulnerabilies in Flash, but the `sandbox` approach seems to |
| more straightforwardly address the threats we care about today. |
| |
| * Asserting the [`Cross-Origin-Opener-Policy`][coop] header with a value |
| of `same-origin` prevents cross-origin documents from retaining a handle |
| to the resource's window if it's opened in a popup. |
| |
| * Sending the `X-Frame-Options` header with a value of `DENY` prevents the |
| resource from being framed. |
| |
| Most subresources, then, should contain the following block of headers, which |
| you'll see repeated a few times below: |
| |
| ```http |
| Content-Security-Policy: sandbox |
| Cross-Origin-Opener-Policy: same-origin |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: DENY |
| ``` |
| |
| With these generic protections in mind, let's sift through a few scenarios to |
| determine what headers a server would be well-served to assert: |
| |
| #### Static Subresources |
| |
| By their nature, static resources contain the same data no matter who requests |
| them, and therefore cannot contain interesting information that an attacker |
| couldn't otherwise obtain. There's no risk to making these resources widely |
| available, and value in allowing embedders to robustly debug, so something like |
| the following response headers could be appropriate: |
| |
| ```http |
| Access-Control-Allow-Origin: * |
| Cross-Origin-Resource-Policy: cross-origin |
| Timing-Allow-Origin: * |
| Content-Security-Policy: sandbox |
| Cross-Origin-Opener-Policy: same-origin |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: DENY |
| ``` |
| |
| CDNs are the canonical static resource distribution points, and many use the |
| pattern above. Take a look at the following common resources' response headers |
| for inspiration: |
| |
| * <a href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js">`https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js`</a> |
| * <a href="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js">`https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js`</a> |
| * <a href="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js">`https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js`</a> |
| * <a href="https://ssl.google-analytics.com/ga.js">`https://ssl.google-analytics.com/ga.js`</a> |
| |
| Similarly, application-specific static resource servers are a good place to look |
| for this practice. Consider: |
| |
| * <a href="https://static.xx.fbcdn.net/rsrc.php/v3/y2/r/zVvRrO8pOtu.png">`https://static.xx.fbcdn.net/rsrc.php/v3/y2/r/zVvRrO8pOtu.png`</a> |
| * <a href="https://www.gstatic.com/images/branding/googlelogo/svg/googlelogo_clr_74x24px.svg">`https://www.gstatic.com/images/branding/googlelogo/svg/googlelogo_clr_74x24px.svg`</a> |
| |
| #### Dynamic Subresources |
| |
| Subresources that contain data personalized to a given user are juicy targets |
| for attackers, and must be defended by ensuring that they're loaded only in |
| ways that are appropriate for the data in question. A few cases are well worth |
| considering: |
| |
| 1. Application-internal resources (private API endpoints, avatar images, |
| uploaded data, etc.) should not be available to any cross-origin requestor. |
| These resources should be restricted to usage as a subresource in |
| same-origin contexts by sending a [`Cross-Origin-Resource-Policy`][corp] |
| header with a value of `same-origin`: |
| |
| ```http |
| Cross-Origin-Resource-Policy: same-origin |
| Content-Security-Policy: sandbox |
| Cross-Origin-Opener-Policy: same-origin |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: DENY |
| ``` |
| |
| This header will prevent cross-origin attackers from loading the resource as |
| a response to a `no-cors` request. |
| |
| For example, examine the headers returned when requesting endpoints like the |
| following: |
| |
| * <a href="https://myaccount.google.com/_/AccountSettingsUi/browserinfo">`https://myaccount.google.com/_/AccountSettingsUi/browserinfo`</a> |
| * <a href="https://twitter.com/i/api/1.1/branch/init.json">`https://twitter.com/i/api/1.1/branch/init.json`</a> |
| * <a href="https://www.facebook.com/ajax/webstorage/process_keys/?state=0">`https://www.facebook.com/ajax/webstorage/process_keys/?state=0`</a> |
| |
| 2. Personalized resources intended for cross-origin use (public API endpoints, |
| etc) should carefully consider incoming requests' properties before |
| responding. These endpoints can only safely be enabled by requiring CORS, |
| and choosing the set of origins for which a given response can be exposed by |
| setting the appropriate access-control headers, for example: |
| |
| ```http |
| Access-Control-Allow-Credentials: true |
| Access-Control-Allow-Origin: https://trusted.example |
| Access-Control-Allow-Methods: POST |
| Access-Control-Allow-Headers: ... |
| Access-Control-Allow-...: ... |
| Cross-Origin-Resource-Policy: same-origin |
| Content-Security-Policy: sandbox |
| Cross-Origin-Opener-Policy: same-origin |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: DENY |
| ``` |
| |
| Note: The `Cross-Origin-Resource-Policy` header is only processed for |
| requests that are _not_ using CORS for access control ("`no-cors` |
| requests"). Sending `Cross-Origin-Resource-Policy: same-origin` is |
| therefore not harmful, and works to ensure that `no-cors` usage isn't |
| accidentally allowed. |
| |
| For example, examine the headers returned when requesting endpoints like |
| the following: |
| |
| * <a href="https://api.twitter.com/1.1/jot/client_event.json">`https://api.twitter.com/1.1/jot/client_event.json`</a> |
| * <a href="https://play.google.com/log?format=json&hasfast=true">`https://play.google.com/log?format=json&hasfast=true`</a> |
| * <a href="https://securepubads.g.doubleclick.net/pcs/view">`https://securepubads.g.doubleclick.net/pcs/view`</a> |
| * <a href="https://c.amazon-adsystem.com/e/dtb/bid">`https://c.amazon-adsystem.com/e/dtb/bid`</a> |
| |
| 3. Personalized resources that are intended for cross-origin `no-cors` |
| embedding, but which don't intend to be directly legible in that context |
| (avatar images, authenticated media, etc). These should enable cross-origin |
| embedding via `Cross-Origin-Resource-Policy`, but _not_ via CORS access |
| control headers: |
| |
| ```http |
| Cross-Origin-Resource-Policy: cross-origin |
| Content-Security-Policy: sandbox |
| Cross-Origin-Opener-Policy: same-origin |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: DENY |
| ``` |
| |
| Note, that this allows the resource to be used by any cross-origin document. |
| That's reasonable for some use cases, but requiring CORS, and opting-in a |
| small set of origins via appropriate access-control headers is a possible |
| alternative for some resources. This approach will give those contexts |
| trivial access to the resource's bits, so the granularity is a tradeoff. |
| Still, considering this case to be the same as the "personalized resources |
| intended for cross-origin use" isn't unreasonable. |
| |
| If we implemented more granular bindings for CORP headers (along the lines |
| of `Cross-Origin-Resource-Policy: https://trusted.example`), we could avoid |
| this tradeoff entirely. That's proposed in |
| [whatwg/fetch#760](https://github.com/whatwg/fetch/issues/670). |
| |
| |
| For example: |
| |
| * <a href="https://lh3.google.com/u/0/d/1JBUaX1xSOZRxBk5bRNZWgnzyJoCQC52TIRokACBSmGc=w512">`https://lh3.google.com/u/0/d/1JBUaX1xSOZRxBk5bRNZWgnzyJoCQC52TIRokACBSmGc=w512`</a> |
| |
| |
| ### Documents {#documents} |
| |
| #### Fully-Isolated Documents |
| |
| Documents that require users to be signed-in almost certainly contain |
| information that shouldn't be revealed to attackers. These pages should take |
| care to isolate themselves from other origins, both by making _a priori_ |
| decisions about [whether to serve the page at all][fetch-metadata], and by |
| giving clients careful instructions about how the page can be used once |
| delivered. For instance, something like the following set of response headers |
| could be appropriate: |
| |
| ```http |
| Cross-Origin-Opener-Policy: same-origin |
| Cross-Origin-Resource-Policy: same-origin |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: SAMEORIGIN |
| ``` |
| |
| Note: Documents which need to make use of APIs that require full cross-origin |
| isolation (such as `SharedArrayBuffer`), will also need to serve a |
| [`Cross-Origin-Embedder-Policy`][coep] header, as outlined in |
| [Making your website "cross-origin isolated" using COOP and COEP][coop-coep]. |
| |
| Account settings pages, admin panels, and application-specific documents are all |
| good examples of resources which would benefit from as much isolation as |
| possible. For real-life examples, consider: |
| |
| * <a href="https://myaccount.google.com/">`https://myaccount.google.com/`</a> |
| |
| [coep]: https://wicg.github.io/cross-origin-embedder-policy/ |
| [coop-coep]: https://web.dev/coop-coep/ |
| |
| |
| #### Documents Expecting to Open Cross-Origin Windows |
| |
| Not every document that requires sign-in can be fully-isolated from the rest of |
| the internet. It's often the case that partial isolation is a better fit. |
| Consider sites that depend upon cross-origin windows for federated workflows |
| involving payments or sign-in, for example. These pages would generally benefit |
| from restricting attackers' ability to embed them, or obtain their window |
| handle, but they can't easily lock themselves off from all such vectors via |
| `Cross-Origin-Opener-Policy: same-origin` and `X-Frame-Options: DENY`. In these |
| cases, something like the following set of response headers might be |
| appropriate: |
| |
| ```http |
| Cross-Origin-Opener-Policy: same-origin-allow-popups |
| Cross-Origin-Resource-Policy: same-origin |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: SAMEORIGIN |
| ``` |
| |
| The only difference between this case and the "Fully-Isolated" case above is the |
| `Cross-Origin-Opener-Policy` value. `same-origin` will break the opener |
| relationship between the document and any cross-origin window, regardless of who |
| opened whom. `same-origin-allow-popups` will break cross-origin opener |
| relationships initiated by a cross-origin document's use of `window.open()`, but |
| will allow the asserting document to open cross-origin windows that retain an |
| opener relationship. |
| |
| |
| #### Documents Expecting Cross-Origin Openers |
| |
| Federated sign-in forms and payment providers are clear examples of documents |
| which intend to be opened by cross-origin windows, and require that relationship |
| to be maintained in order to facilitate communication via channels like |
| `postMessage()` or navigation. These documents cannot isolate themselves |
| completely, but can prevent themselves from being embedded or fetched |
| cross-origin. Three scenarios are worth considering: |
| |
| 1. Documents that only wish to be opened in cross-origin popups could loosen |
| their cross-origin opener policy by serving the following headers: |
| |
| ```http |
| Cross-Origin-Resource-Policy: same-origin |
| Cross-Origin-Opener-Policy: unsafe-none |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: SAMEORIGIN |
| ``` |
| |
| For example: |
| |
| * > TODO: Find some links. |
| |
| 2. Documents that only wish to be framed in cross-origin contexts could loosen |
| their framing protections by serving the following headers: |
| |
| ```http |
| Cross-Origin-Resource-Policy: same-origin |
| Cross-Origin-Opener-Policy: same-origin |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: ALLOWALL |
| ``` |
| |
| |
| Note that this allows embedding by any cross-origin documents. That's |
| reasonable for some widgety use cases, but when possible, a more secure |
| alternative would specify a list of origins which are allowed to embed the |
| document via the `frame-ancestors` CSP directive. That is, in addition to |
| the `X-Frame-Options` header above, the following header could also be |
| included to restrict the document to a short list of trusted embedders: |
| |
| ```http |
| Content-Security-Policy: frame-ancestors https://trusted1.example https://trusted2.example |
| ``` |
| |
| For example: |
| |
| * > TODO: Find some links. |
| |
| 3. Documents that support both popup and framing scenarios need to loosen both |
| their cross-origin opener policies and framing protections by combining the |
| recommendations above, serving the following headers: |
| |
| ```http |
| Cross-Origin-Resource-Policy: same-origin |
| Cross-Origin-Opener-Policy: unsafe-none |
| Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site |
| X-Content-Type-Options: nosniff |
| X-Frame-Options: ALLOWALL |
| ``` |
| |
| For example: |
| |
| * > TODO: Find some links. |
| |
| ## Implementation Considerations |
| |
| ### Explicitly Setting Headers with Default Values |
| |
| Several recommendations above suggest that developers would be well-served to |
| set headers like `X-Frame-Options: ALLOWALL` or `Cross-Origin-Opener-Policy: |
| unsafe-none` on responses. These map to the web's status quo behavior, and seem |
| therefore superfluous. Why should developers set them? |
| |
| The core reason is that these defaults are poor fits for today's threats, and we |
| ought to be working to change them. Proposals like [Embedding Requires Opt-In][embedding] |
| and [COOP By Default][coop-by-default] suggest that we should shift the web's |
| defaults away from requiring developers to opt-into more secure behaviors by |
| making them opt-out rather than opt-in. This would place the configuration cost |
| on those developers whose projects require risky settings. |
| |
| This document recommends setting those less-secure header values explicitly, as |
| that makes it more likely that we'll be able to shift the web's defaults in the |
| future. |
| |
| [embedding]: https://github.com/mikewest/embedding-requires-opt-in |
| [coop-by-default]: https://github.com/mikewest/coop-by-default |
| |
| ## Acknowledgements |
| |
| This document relies upon a number of excellent resources that spell out much of |
| the foundation of our understanding of Spectre's implications for the web, and |
| justify the mitigation strategies we currently espouse. The following is an |
| incomplete list of those works, in no particular order: |
| |
| * Chris Palmer's |
| [Isolating Application-Defined Principles](https://noncombatant.org/application-principals/) |
| |
| * Charlie Reis' |
| [Long-Term Web Browser Mitigations for Spectre](https://docs.google.com/document/d/1dnUjxfGWnvhQEIyCZb0F2LmCZ9gio6ogu2rhMGqi6gY/edit) |
| |
| * Anne van Kesteren's |
| [A Spectre-Shaped Web](https://docs.google.com/presentation/d/1sadl7jTrBIECCanuqSrNndnDr82NGW1yyuXFT1Dc7SQ/edit#slide=id.p), |
| [Safely Reviving Shared Memory](https://hacks.mozilla.org/2020/07/safely-reviving-shared-memory/), |
| and [Opaque Resource Blocking](https://github.com/annevk/orb). |
| |
| * Artur Janc and Mike West's [How do we stop spilling the beans across origins?](https://www.arturjanc.com/cross-origin-infoleaks.pdf) |
| |
| * Mike West's [Cross-Origin Embedder Policy explainer](https://wicg.github.io/cross-origin-embedder-policy/) |
| |
| * Charlie Reis and Camille Lamy's [Cross-Origin Opener Policy explainer](https://docs.google.com/document/d/1Ey3MXcLzwR1T7aarkpBXEwP7jKdd2NvQdgYvF8_8scI/edit) |
| |
| * Artur Janc, Charlie Reis, and Anne van Kesteren's [COOP and COEP Explained](https://docs.google.com/document/d/1Ey3MXcLzwR1T7aarkpBXEwP7jKdd2NvQdgYvF8_8scI/edit) |
| |
| * Artur Janc's [Notes on the threat model of cross-origin isolation](https://arturjanc.com/coi-threat-model.pdf) |