• HTTP
  • An overview of HTTP
  • Compression in HTTP
  • Redirections in HTTP
  • Connection management in HTTP/1.x
  • HTTP Client hints
  • Security and privacy
    1. Permissions Policy Experimental
    2. Headers
  • References
  • HTTP headers
    1. Accept-Language
    2. Access-Control-Allow-Credentials
    3. Access-Control-Expose-Headers
    4. Age
    5. Attribution-Reporting-Eligible Experimental
    6. Attribution-Reporting-Register-Source Experimental
    7. Attribution-Reporting-Register-Trigger Experimental
    8. Connection
    9. Content-DPR Non-standard Deprecated
    10. Content-Location
    11. Content-Type
    12. Critical-CH Experimental
    13. Date
    14. DNT Non-standard Deprecated
    15. Downlink Experimental
    16. DPR Non-standard Deprecated
    17. Early-Data Experimental
    18. ECT Experimental
    19. Expect-CT Deprecated
    20. Host
    21. If-Range
    22. Link
    23. NEL Experimental
    24. No-Vary-Search Experimental
    25. Observe-Browsing-Topics Experimental Non-standard
    26. Origin-Agent-Cluster Experimental
    27. Permissions-Policy Experimental
    28. Pragma Deprecated
    29. Range
    30. Report-To Non-standard Deprecated
    31. Reporting-Endpoints Experimental
    32. RTT Experimental
    33. Save-Data Experimental
    34. Sec-Browsing-Topics Experimental Non-standard
    35. Sec-CH-Prefers-Color-Scheme Experimental
    36. Sec-CH-Prefers-Reduced-Motion Experimental
    37. Sec-CH-Prefers-Reduced-Transparency Experimental
    38. Sec-CH-UA Experimental
    39. Sec-CH-UA-Arch Experimental
    40. Sec-CH-UA-Bitness Experimental
    41. Sec-CH-UA-Form-Factors Experimental
    42. Sec-CH-UA-Full-Version Deprecated
    43. Sec-CH-UA-Full-Version-List Experimental
    44. Sec-CH-UA-Mobile Experimental
    45. Sec-CH-UA-Model Experimental
    46. Sec-CH-UA-Platform Experimental
    47. Sec-CH-UA-Platform-Version Experimental
    48. Sec-CH-UA-WoW64 Experimental
    49. Sec-Fetch-User
    50. Sec-GPC Experimental
    51. Sec-WebSocket-Key
    52. Server-Timing
    53. Set-Cookie
    54. Set-Login Experimental
    55. Speculation-Rules Experimental
    56. Supports-Loading-Mode Experimental
    57. Tk Non-standard Deprecated
    58. Upgrade-Insecure-Requests
    59. Viewport-Width Non-standard Deprecated
    60. Warning Deprecated
    61. Width Non-standard Deprecated
    62. X-DNS-Prefetch-Control Non-standard
    63. X-Forwarded-For Non-standard
    64. X-Forwarded-Host Non-standard
    65. X-Forwarded-Proto Non-standard
    66. X-Permitted-Cross-Domain-Policies Non-standard
    67. X-Powered-By Non-standard
    68. X-Robots-Tag Non-standard
    69. X-XSS-Protection Non-standard Deprecated
  • HTTP request methods
    1. HEAD
    2. PUT
    3. 102 Processing
    4. 202 Accepted
    5. 206 Partial Content
    6. 300 Multiple Choices
    7. 304 Not Modified
    8. 401 Unauthorized
    9. 405 Method Not Allowed
    10. 409 Conflict
    11. 413 Content Too Large
    12. 417 Expectation Failed
    13. 423 Locked
    14. 428 Precondition Required
    15. 500 Internal Server Error
    16. 504 Gateway Timeout
    17. 508 Loop Detected
    18. CSP: block-all-mixed-content Deprecated
    19. CSP: fenced-frame-src Experimental
    20. CSP: frame-src
    21. CSP: object-src
    22. CSP: prefetch-src Non-standard Deprecated
    23. CSP: report-uri Deprecated
    24. CSP: require-trusted-types-for Experimental
    25. CSP: script-src-elem
    26. CSP: trusted-types Experimental
    27. Reason: CORS header 'Access-Control-Allow-Origin' does not match 'xyz'
    28. Reason: CORS request did not succeed
    29. Reason: Did not find method in CORS header 'Access-Control-Allow-Methods'
    30. Reason: missing token 'xyz' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel
    31. Permissions-Policy: accelerometer Experimental
    32. Permissions-Policy: ambient-light-sensor Experimental
    33. Permissions-Policy: attribution-reporting Experimental
    34. Permissions-Policy: autoplay Experimental
    35. Permissions-Policy: bluetooth Experimental
    36. Permissions-Policy: browsing-topics Experimental Non-standard
    37. Permissions-Policy: camera Experimental
    38. Permissions-Policy: compute-pressure Experimental
    39. Permissions-Policy: cross-origin-isolated Experimental
    40. Permissions-Policy: display-capture Experimental
    41. Permissions-Policy: document-domain Experimental
    42. Permissions-Policy: encrypted-media Experimental
    43. Permissions-Policy: fullscreen Experimental
    44. Permissions-Policy: gamepad Experimental
    45. Permissions-Policy: geolocation Experimental
    46. Permissions-Policy: gyroscope Experimental
    47. Permissions-Policy: hid Experimental
    48. Permissions-Policy: identity-credentials-get Experimental
    49. Permissions-Policy: idle-detection Experimental
    50. Permissions-Policy: local-fonts Experimental
    51. Permissions-Policy: magnetometer Experimental
    52. Permissions-Policy: microphone Experimental
    53. Permissions-Policy: midi Experimental
    54. Permissions-Policy: otp-credentials Experimental
    55. Permissions-Policy: payment Experimental
    56. Permissions-Policy: picture-in-picture Experimental
    57. Permissions-Policy: publickey-credentials-create Experimental
    58. Permissions-Policy: publickey-credentials-get Experimental
    59. Permissions-Policy: screen-wake-lock Experimental
    60. Permissions-Policy: serial Experimental
    61. Permissions-Policy: speaker-selection Experimental
    62. Permissions-Policy: storage-access Experimental
    63. Permissions-Policy: usb Experimental
    64. Permissions-Policy: web-share Experimental
    65. Permissions-Policy: window-management Experimental
    66. Permissions-Policy: xr-spatial-tracking Experimental
  • browsing context group (BCG) or in a new browsing context group.

    When opened in a new BCG, any references between the new document and its opener are severed, and the new document may be process-isolated from its opener. This ensures that potential attackers can't open your documents with Window.open() and then use the returned value to access its global object, and thereby prevents a set of cross-origin attacks referred to as XS-Leaks.

    It also means that any object opened by your document in a new BCG can't access it using window.opener. This allows you to have more control over references to a window than Window.open().

    The behaviour depends on the policies of both the new document and its opener, and whether the new document is opened following a navigation or using Window.open().

    Header type Response header
    Forbidden request header No
  • Syntax

    http
    Cross-Origin-Opener-Policy: unsafe-none
    Cross-Origin-Opener-Policy: same-origin-allow-popups
    Cross-Origin-Opener-Policy: same-origin
    Cross-Origin-Opener-Policy: noopener-allow-popups
    

    Directives

    unsafe-none

    The document permits sharing its browsing context group with any other document, and may therefore be unsafe. It is used to opt-out a document from using COOP for process isolation. This is the default value.

    On navigations, documents with unsafe-none will always open and be opened into a new BCG — unless the other document also has unsafe-none (or no COOP directive value).

    Using Window.open(), documents with unsafe-none will always open documents with any other value into a new BCG. However documents with unsafe-none can be opened in the same BCG if the opener has the directive same-origin-allow-popups, noopener-allow-popups, or unsafe-none. A document with same-origin will always open a document with unsafe-none in a new BCG.

    same-origin

    The document permits loading into BCGs that use COOP and contain only same-origin documents. This is used to provide cross-origin isolation for a BCG.

    Documents with same-origin will only open and be opened in the same BCG if both documents are same-origin and have the same-origin directive.

    same-origin-allow-popups

    This is similar to same-origin directive, except that it allows the opening of documents using Window.open() in the same BCG if they have a COOP value of unsafe-none.

    The directive is used to relax the same-origin restriction for integrations where a document needs the benefits of cross-origin isolation but also needs to open and retain a reference to trusted cross-origin documents. For example, when using a cross-origin service for OAuth or payments.

    A document with this directive can open a document in the same BCG using Window.open() if it has a COOP value of unsafe-none. In this case it does not matter if the opened document is cross-site or same-site.

    Otherwise documents with same-origin-allow-popups will only open and be opened in the same BCG if both documents are same-origin and have the same-origin-allow-popups directive.

    noopener-allow-popups

    Documents with this directive are always opened into a new BCG, except when opened by navigating from a document that also has noopener-allow-popups. It is used to support cases where there is a need to process-isolate same-origin documents.

    This severs the connections between the new document and its opener, isolating the browsing context for the current document regardless of the opener document's origin. This ensures that the opener can't run scripts in opened documents and vice versa — even if they are same-origin.

    On navigations, a document with this directive will always open other documents in a new BCG unless they are same-origin and have the directive noopener-allow-popups. Using Window.open(), a document with this directive will open documents in a new BCG unless they have unsafe-none, and in this case it does not matter if they are same-site or cross-site.

    Description

    Generally you should set your policies such that only same-origin and trusted cross-origin resources that need to be able to script each other should be allowed to be opened in the same browser context group. Other resources should be cross-origin isolated in their own group.

    The following sections show whether documents will be opened in the same BCG or a new BCD following a navigation or opening a window programmatically.

    Note: The specification uses the term "popup" to refer to any document opened using Window.open(), whether it is a popup, tab, window, or other context.

    When navigating between documents, the new document is opened in the same BCG if the two documents have "matching coop policies", and otherwise into a new BCG.

    The policies match if:

    • both documents are unsafe-none, or
    • neither document is unsafe-none, their policy values are the same, and they are same-origin.

    The table below shows the result of this rule on whether documents are opened in the same or a new BCG for the different directive values.

    Opener (row) / Opened (col) unsafe-none same-origin-allow-popups same-origin noopener-allow-popups
    unsafe-none Same New
    same-origin-allow-popups New Same if same-origin New
    same-origin New Same if same-origin New
    noopener-allow-popups New Same if same-origin

    Opening with Window.open()

    When opening a document using Window.open(), the new document is opened in the same BCG according to the following rules, which are evaluated in order:

    1. True: opened noopener-allow-popups
    2. False: (opener same-origin-allow-popups or noopener-allow-popups) and (opened document is unsafe-none)
    3. False: Matching COOP policies (as outlined above for navigations)
    4. True: Otherwise!

    The table below shows the opener behaviour for the different directive values.

    Opener (row) / Opened (col) unsafe-none same-origin-allow-popups same-origin noopener-allow-popups
    unsafe-none Same New
    same-origin-allow-popups Same Same if same-origin New
    same-origin New Same if same-origin New
    noopener-allow-popups Same New

    Examples

    Features that depend on cross-origin isolation

    Certain features, such as access to cross-origin isolated.

    To use these features in a document, you will need to set the COOP header to same-origin and the Cross-Origin-Embedder-Policy header to require-corp (or credentialless). In addition the feature must not be blocked by Permissions-Policy: cross-origin-isolated.

    http
    Cross-Origin-Opener-Policy: same-origin
    Cross-Origin-Embedder-Policy: require-corp
    

    You can use the WorkerGlobalScope.crossOriginIsolated properties to check if a document is cross-origin isolated, and hence whether or not the features are restricted:

    js
    const myWorker = new Worker("worker.js");
    
    if (crossOriginIsolated) {
      const buffer = new SharedArrayBuffer(16);
      myWorker.postMessage(buffer);
    } else {
      const buffer = new ArrayBuffer(16);
      myWorker.postMessage(buffer);
    }
    

    Severing the opener relationship

    Consider a hypothetical origin example.com that has two very different applications on the same origin:

    • A chat application at /chat that enables any user to contact any other user and send them messages.
    • A password management application at /passwords that contains all of the user's passwords, across different services.

    The administrators of the "passwords" application would very much like to ensure that it can't be directly scripted by the "chat" app, which by its nature has a larger XSS surface. The "right way" to isolate these applications would be to host them on different origins, but in some cases that's not possible, and those two applications have to be on a single origin for historical, business, or branding reasons.

    The Cross-Origin-Opener-Policy: noopener-allow-popups header can be used to ensure that a document can't be scripted by a document that opens it.

    If example.com/passwords is served with noopener-allow-popups the WindowProxy returned by Window.closed is true), so the opener can't script the passwords app:

    js
    const handle = window.open("example.com/passwords", "passwordTab");
    if (windowProxy.closed) {
      / The new window is closed so it can't be scripted.
    }
    

    Note that this alone is not considered a sufficient security measure. The site would also need to do the following:

    • Use Fetch Metadata to block same-origin requests to the more-sensitive app that are not navigation requests.
    • Ensure their authentication cookies are all HttpOnly.
    • Ensure root-level Service-Workers are not installed by the less-sensitive app.
    • Ensure that postMessage or BroadcastChannel on the more-sensitive app don't expose any sensitive information the any other same-origin app.
    • Ensure their login page is served on a separate origin, due to password manager autofill being applied based on origin.
    • Understand that the browser may still allocate the more-sensitive app in the same process as the less-sensitive one, making it vulnerable to Spectre-like attacks.

    Specifications

    Specification
    HTML
    # the-coop-headers

    Browser compatibility

    BCD tables only load in the browser

    See also