Bug 238238 - Incorrect CORP/COEP check in 304 responses
Summary: Incorrect CORP/COEP check in 304 responses
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: Safari Technology Preview
Hardware: All All
: P2 Major
Assignee: Nobody
Keywords: InRadar
Depends on:
Reported: 2022-03-22 16:28 PDT by Aleksandr Dobkin
Modified: 2022-04-08 01:32 PDT (History)
13 users (show)

See Also:

Patch (94.58 KB, patch)
2022-04-04 05:50 PDT, Carlos Garcia Campos
youennf: review+
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch for landing (94.67 KB, patch)
2022-04-05 04:51 PDT, Carlos Garcia Campos
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch for landing (94.67 KB, patch)
2022-04-07 03:42 PDT, Carlos Garcia Campos
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Aleksandr Dobkin 2022-03-22 16:28:07 PDT
When processing 304 (Not Modified) responses, Safari/WebKit blocks the resource even when it should be allowed according to CORP (Cross-Origin-Resource-Policy).

Background: When a top-level page is served with the COEP (Cross-Origin-Embedder-Policy) and COOP (Cross-Origin-Opener-Policy) headers, it is considered cross-origin isolated. The browser requires that the CORP header be present on cross-origin subresources in this case.

According to the HTTP spec, the CORP header must appear on 200 responses but SHOULD NOT appear on 304 responses. However, Safari blocks loading of the resource if the CORP header is missing on the 304 response. The correct behavior is to use the cached value of the header. This behavior causes intermittent failure to load resources in production websites. Caching mechanisms implemented by Apache, etc, automatically discard non-standard headers on 304 responses so this is difficult to work around on the server side.

Demo/proof of concept: https://adobkin.name/test/corp304.php

Steps to repro:

  1. Serve an HTTPS page with with the following headers to opt-in to cross-origin isolation:

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

     Verify that `window.crossOriginIsolated` is true.

  2. Load a cross-origin resource, e.g.

     <script src="//example.com/resource.js">

     The resource should be served with something along these lines

    header('cache-control: no-cache');
    header('content-type: text/javascript');
    header('Cross-Origin-Resource-Policy: cross-origin', true);
    if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
        header("HTTP/1.1 304 Not Modified"); 
    header('last-modified: Tue, 08 Mar 2022 11:47:39 GMT');
  3. Check that the resource loads successfully on the initial page load. The server will reply with 200 OK.

  4. Upon reload, the resource will load using 304 (Not Modified) and will be blocked due to lack of CORP headers. 

Similar Chromium issue: https://bugs.chromium.org/p/chromium/issues/detail?id=1241264
Comment 1 Radar WebKit Bug Importer 2022-03-23 10:04:59 PDT
Comment 2 Carlos Garcia Campos 2022-04-04 05:50:26 PDT
Created attachment 456562 [details]
Comment 3 youenn fablet 2022-04-04 11:58:46 PDT
Comment on attachment 456562 [details]

r=me once bots are happy.
Some of these tests probably need DumpJSConsoleLogInStdErr.
Comment 4 Carlos Garcia Campos 2022-04-05 04:51:47 PDT
Created attachment 456692 [details]
Patch for landing
Comment 5 Carlos Garcia Campos 2022-04-06 02:52:50 PDT
It seems imported/w3c/web-platform-tests/html/cross-origin-embedder-policy/report-only-require-corp.https.html is crashing in ios-wk2, but I can't see the bt in the results.
Comment 6 Carlos Garcia Campos 2022-04-07 03:42:15 PDT
Created attachment 456903 [details]
Patch for landing
Comment 7 EWS 2022-04-08 01:32:07 PDT
Committed r292595 (249428@main): <https://commits.webkit.org/249428@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 456903 [details].