Commit 083bfc36 authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

[COEP] Fix up navigation CORP

Spec: the sixth item of
https://mikewest.github.io/corpp/#integration-html

Fix stale implementation, and add reporting.

 - Run CORP on redirects.
 - Use the parent COEP instead of the response COEP value.
 - Add reporting plumbing.

Bug: 887967, 1052764
Change-Id: I3723e671fb7d571dcce741f859d8d831ae7c584e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2089183
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Auto-Submit: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarArthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: default avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748696}
parent 01579889
...@@ -1572,6 +1572,16 @@ void NavigationRequest::OnRequestRedirected( ...@@ -1572,6 +1572,16 @@ void NavigationRequest::OnRequestRedirected(
return; return;
} }
if (const auto blocked_reason = IsBlockedByCorp()) {
OnRequestFailedInternal(network::URLLoaderCompletionStatus(*blocked_reason),
false /* skip_throttles */,
base::nullopt /* error_page_content */,
false /* collapse_frame */);
// DO NOT ADD CODE after this. The previous call to
// OnRequestFailedInternal has destroyed the NavigationRequest.
return;
}
// For now, DevTools needs the POST data sent to the renderer process even if // For now, DevTools needs the POST data sent to the renderer process even if
// it is no longer a POST after the redirect. // it is no longer a POST after the redirect.
if (redirect_info.new_method != "POST") if (redirect_info.new_method != "POST")
...@@ -1798,52 +1808,43 @@ void NavigationRequest::OnResponseStarted( ...@@ -1798,52 +1808,43 @@ void NavigationRequest::OnResponseStarted(
} }
} }
if (const auto blocked_reason = IsBlockedByCorp()) {
OnRequestFailedInternal(network::URLLoaderCompletionStatus(*blocked_reason),
false /* skip_throttles */,
base::nullopt /* error_page_content */,
false /* collapse_frame */);
// DO NOT ADD CODE after this. The previous call to
// OnRequestFailedInternal has destroyed the NavigationRequest.
return;
}
auto cross_origin_embedder_policy = auto cross_origin_embedder_policy =
response_head_->cross_origin_embedder_policy; response_head_->cross_origin_embedder_policy;
if (base::FeatureList::IsEnabled(network::features::kCrossOriginIsolation)) { if (base::FeatureList::IsEnabled(network::features::kCrossOriginIsolation)) {
// https://mikewest.github.io/corpp/#process-navigation-response. // https://mikewest.github.io/corpp/#integration-html
if (GetParentFrame() && if (auto* const parent_frame = GetParentFrame()) {
cross_origin_embedder_policy.value == const auto& parent_coep = parent_frame->cross_origin_embedder_policy();
network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp && const auto& url = common_params_->url;
!common_params_->url.SchemeIsBlob() && if (parent_coep.value ==
!common_params_->url.SchemeIs(url::kDataScheme)) { network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp) {
// The CORP check for nested navigation. if (url.SchemeIsBlob() || url.SchemeIs(url::kDataScheme)) {
if (base::Optional<network::BlockedByResponseReason> blocked_reason = // Some special URLs not loaded using the network are inheriting the
network::CrossOriginResourcePolicy::IsNavigationBlocked( // Cross-Origin-Embedder-Policy header from their parent.
common_params_->url, redirect_chain_[0], cross_origin_embedder_policy.value =
GetParentFrame()->GetLastCommittedOrigin(), *response_head_, network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp;
GetParentFrame()->GetLastCommittedOrigin(), }
cross_origin_embedder_policy)) { if (cross_origin_embedder_policy.value ==
OnRequestFailedInternal( network::mojom::CrossOriginEmbedderPolicyValue::kNone) {
network::URLLoaderCompletionStatus(*blocked_reason), OnRequestFailedInternal(network::URLLoaderCompletionStatus(
false /* skip_throttles */, base::nullopt /* error_page_content */, network::BlockedByResponseReason::
false /* collapse_frame */); kCoepFrameResourceNeedsCoepHeader),
// DO NOT ADD CODE after this. The previous call to false /* skip_throttles */,
// OnRequestFailedInternal has destroyed the NavigationRequest. base::nullopt /* error_page_content */,
return; false /* collapse_frame */);
} // DO NOT ADD CODE after this. The previous call to
} // OnRequestFailedInternal has destroyed the NavigationRequest.
if (GetParentFrame() && return;
GetParentFrame()->cross_origin_embedder_policy().value == }
network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp) {
// Some special URLs not loaded using the network are inheriting the
// Cross-Origin-Embedder-Policy header from their parent.
if (common_params_->url.SchemeIsBlob() ||
common_params_->url.SchemeIs(url::kDataScheme)) {
cross_origin_embedder_policy.value =
network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp;
}
if (cross_origin_embedder_policy.value ==
network::mojom::CrossOriginEmbedderPolicyValue::kNone) {
OnRequestFailedInternal(network::URLLoaderCompletionStatus(
network::BlockedByResponseReason::
kCoepFrameResourceNeedsCoepHeader),
false /* skip_throttles */,
base::nullopt /* error_page_content */,
false /* collapse_frame */);
// DO NOT ADD CODE after this. The previous call to
// OnRequestFailedInternal has destroyed the NavigationRequest.
return;
} }
} }
...@@ -4033,6 +4034,29 @@ void NavigationRequest::ForceEnableOriginTrials( ...@@ -4033,6 +4034,29 @@ void NavigationRequest::ForceEnableOriginTrials(
commit_params_->force_enabled_origin_trials = trials; commit_params_->force_enabled_origin_trials = trials;
} }
base::Optional<network::BlockedByResponseReason>
NavigationRequest::IsBlockedByCorp() {
if (!base::FeatureList::IsEnabled(network::features::kCrossOriginIsolation)) {
return base::nullopt;
}
// https://mikewest.github.io/corpp/#integration-html
auto* parent_frame = GetParentFrame();
if (!parent_frame) {
return base::nullopt;
}
const auto& url = common_params_->url;
// Some special URLs not loaded using the network are inheriting the
// Cross-Origin-Embedder-Policy header from their parent.
if (url.SchemeIsBlob() || url.SchemeIs(url::kDataScheme)) {
return base::nullopt;
}
return network::CrossOriginResourcePolicy::IsNavigationBlocked(
url, redirect_chain_[0], parent_frame->GetLastCommittedOrigin(),
*response_head_, parent_frame->GetLastCommittedOrigin(),
parent_frame->cross_origin_embedder_policy(),
parent_frame->coep_reporter());
}
std::unique_ptr<PeakGpuMemoryTracker> std::unique_ptr<PeakGpuMemoryTracker>
NavigationRequest::TakePeakGpuMemoryTracker() { NavigationRequest::TakePeakGpuMemoryTracker() {
return std::move(loading_mem_tracker_); return std::move(loading_mem_tracker_);
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/proxy_server.h" #include "net/base/proxy_server.h"
#include "net/dns/public/resolve_error_info.h" #include "net/dns/public/resolve_error_info.h"
#include "services/network/public/cpp/blocked_by_response_reason.h"
#include "services/network/public/cpp/origin_policy.h" #include "services/network/public/cpp/origin_policy.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
...@@ -876,6 +877,8 @@ class CONTENT_EXPORT NavigationRequest ...@@ -876,6 +877,8 @@ class CONTENT_EXPORT NavigationRequest
void ForceEnableOriginTrials(const std::vector<std::string>& trials) override; void ForceEnableOriginTrials(const std::vector<std::string>& trials) override;
base::Optional<network::BlockedByResponseReason> IsBlockedByCorp();
FrameTreeNode* frame_tree_node_; FrameTreeNode* frame_tree_node_;
// Invariant: At least one of |loader_| or |render_frame_host_| is null. // Invariant: At least one of |loader_| or |render_frame_host_| is null.
......
...@@ -84,8 +84,6 @@ async_test(t => { ...@@ -84,8 +84,6 @@ async_test(t => {
assert_equals(win, null); assert_equals(win, null);
}, `"require-corp" top-level noopener popup: navigating to "none" should succeed`); }, `"require-corp" top-level noopener popup: navigating to "none" should succeed`);
// CORP is checked because COEP of the frame is "require-corp". The parent
// frame's COEP value doesn't matter.
async_test(t => { async_test(t => {
const frame = document.createElement("iframe"); const frame = document.createElement("iframe");
const id = token(); const id = token();
...@@ -96,33 +94,8 @@ async_test(t => { ...@@ -96,33 +94,8 @@ async_test(t => {
t.done(); t.done();
} }
})); }));
// REMOTE_ORIGIN is cross-origin, same-site.
frame.src = `${HOST.HTTPS_REMOTE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`;
document.body.append(frame);
}, 'CORP: same-site is checked and allowed.');
// CORP is checked because COEP of the frame is "require-corp". The parent
// frame's COEP value doesn't matter.
async_test(t => {
const frame = document.createElement("iframe");
const id = token();
t.add_cleanup(() => frame.remove());
let loaded = false;
window.addEventListener('message', t.step_func((e) => {
if (e.data === id) {
loaded = true;
}
}));
t.step_timeout(() => {
// Make sure the iframe didn't load. See https://github.com/whatwg/html/issues/125 for why a
// timeout is used here. Long term all network error handling should be similar and have a
// reliable event.
assert_false(loaded);
t.done();
}, 2000);
// NOTESAMESITE_ORIGIN is cross-origin, cross-site.
frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`; frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}${BASE}/navigate-require-corp-same-site.sub.html?token=${id}`;
document.body.append(frame); document.body.append(frame);
}, 'CORP: same-site is checked and blocked.'); }, 'CORP: same-site is not checked.');
</script> </script>
...@@ -8,61 +8,139 @@ ...@@ -8,61 +8,139 @@
<script src="/common/get-host-info.sub.js"></script> <script src="/common/get-host-info.sub.js"></script>
<script> <script>
const HOST = get_host_info(); const HOST = get_host_info();
function getIframeUrl(filename, token1, token2) { const REMOTE_ORIGIN = HOST.REMOTE_ORIGIN;
let query = `template=${filename}`; const BASE = new URL("resources", location).pathname
if (token1) {
query += `&coep=${token1}` function wait(ms) {
return new Promise(resolve => step_timeout(resolve, ms));
}
async function pollReports(endpoint, reports) {
while (true) {
await wait(200);
const res = await fetch(`resources/report.py?endpoint=${endpoint}`, {cache: 'no-store'});
if (res.status !== 200) {
continue;
}
for (const report of await res.json()) {
reports.push(report);
}
} }
if (token2) { }
query += `&coep-report-only=${token2}`
let reports = []
let reportsForReportOnly = []
pollReports('endpoint', reports);
pollReports('report-only-endpoint', reportsForReportOnly);
function checkCorpReportExistence(reports, blockedUrl, contextUrl) {
blockedUrl = new URL(blockedUrl, location).href;
contextUrl = new URL(contextUrl, location).href;
for (const report of reports) {
if (report.type !== 'coep' || report.url !== contextUrl ||
report.body.type !== 'corp') {
continue;
}
if (report.body['blocked-url'] === blockedUrl) {
return;
}
} }
return `resources/reporting-iframe.py?${query}`; assert_unreached(`A report whose blocked-url is ${blockedUrl} and url is ${contextUrl} is not found.`);
} }
function checkReports(reports, contextUrl) { function checkReportNonExistence(reports, blockedUrl, contextUrl) {
assert_not_equals(reports, null); blockedUrl = new URL(blockedUrl, location).href;
assert_equals(reports.length, 2); contextUrl = new URL(contextUrl, location).href;
assert_equals(reports[0].type, 'coep'); for (const report of reports) {
assert_equals(reports[0].url, contextUrl); if (report.type !== 'coep' || report.url !== contextUrl) {
assert_equals(reports[0].body.type, 'corp'); continue;
assert_equals(reports[1].type, 'coep'); }
assert_equals(reports[1].url, contextUrl); assert_not_equals(report.body['blocked-url'], blockedUrl);
assert_equals(reports[1].body.type, 'corp'); }
// The order of the reports is non-deterministic.
const actualBlockedUrls = reports.map((r) => r.body['blocked-url']).sort();
const expectedBlockedUrls = [
`${HOST.REMOTE_ORIGIN}/common/text-plain.txt`,
`${HOST.ORIGIN}/common/redirect.py?location=${HOST.REMOTE_ORIGIN}/common/text-plain.txt`,
];
assert_array_equals(actualBlockedUrls.sort(), expectedBlockedUrls.sort());
} }
async_test(async (t) => { async_test(async (t) => {
try { try {
const iframe = document.createElement('iframe'); const iframe = document.createElement('iframe');
t.add_cleanup(() => iframe.remove()); t.add_cleanup(() => iframe.remove());
const token1 = token();
const token2 = token();
iframe.src = `resources/subresource-corp.html?token1=${token1}&token2=${token2}`; iframe.src = `resources/reporting-empty-frame.html`
document.body.appendChild(iframe); document.body.appendChild(iframe);
await new Promise(resolve => {
iframe.addEventListener('load', resolve, {once: true});
});
function fetchInIframe(url) {
const init = { mode: 'no-cors', cache: 'no-store' };
iframe.contentWindow.fetch(url, init).catch(() => {});
}
const suffix = 'subresource-corp';
const sameOriginUrl = `/common/text-plain.txt?${suffix}`;
const blockedByPureCorp = `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt?${suffix}`;
const blockedDueToCoep = `${REMOTE_ORIGIN}/common/text-plain.txt?abc&${suffix}`;
const dest = `${REMOTE_ORIGIN}/common/text-plain.txt?xyz&${suffix}`;
const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`;
fetchInIframe(sameOriginUrl);
fetchInIframe(blockedByPureCorp);
fetchInIframe(blockedDueToCoep);
fetchInIframe(redirect);
await new Promise(resolve => t.step_timeout(resolve, 3000)); await new Promise(resolve => t.step_timeout(resolve, 3000));
const res1 = await fetch(`resources/stash-take.py?key=${token1}`); checkReportNonExistence(reports, sameOriginUrl, iframe.src);
const res2 = await fetch(`resources/stash-take.py?key=${token2}`); checkReportNonExistence(reports, blockedByPureCorp, iframe.src);
checkCorpReportExistence(reports, blockedDueToCoep, iframe.src);
checkCorpReportExistence(reports, redirect, iframe.src);
checkReportNonExistence(reports, dest, iframe.src);
t.done();
} catch (e) {
t.step(() => { throw e });
}
}, 'subresource CORP');
async_test(async (t) => {
try {
const iframe = document.createElement('iframe');
t.add_cleanup(() => iframe.remove());
iframe.src = `resources/reporting-empty-frame.html`
document.body.appendChild(iframe);
await new Promise(resolve => {
iframe.addEventListener('load', resolve, {once: true});
});
const w = iframe.contentWindow;
const reports = JSON.parse(await res1.text()); function attachFrame(url) {
const reportsForReportOnly = JSON.parse(await res2.text()); const frame = w.document.createElement('iframe');
frame.src = url;
w.document.body.appendChild(frame);
}
checkReports(reports, iframe.src); const suffix = 'navigation-corp';
checkReports(reportsForReportOnly, iframe.src); const sameOrigin = `/common/blank.html?${suffix}`;
const blockedDueToCoep = `${REMOTE_ORIGIN}/common/blank.html?abc&${suffix}`;
const dest = `${REMOTE_ORIGIN}/common/blank.html?xyz&${suffix}`;
const redirect = `/common/redirect.py?location=${encodeURIComponent(dest)}&${suffix}`;
attachFrame(sameOrigin);
attachFrame(blockedDueToCoep);
attachFrame(redirect);
await new Promise(resolve => t.step_timeout(resolve, 3000));
checkReportNonExistence(reports, sameOrigin, iframe.src);
checkCorpReportExistence(reports, blockedDueToCoep, iframe.src);
checkCorpReportExistence(reports, redirect, iframe.src);
checkReportNonExistence(reports, dest, iframe.src);
t.done(); t.done();
} catch (e) { } catch (e) {
t.step(() => { throw e }); t.step(() => { throw e });
}; }
}, 'report-to parameter for COEP and COEP-report-only'); }, 'navigation CORP');
</script> </script>
report-to: { "group": "endpoint", "max_age": 10886400, "endpoints": [{ "url": "https://{{hosts[][www]}}:{{ports[https][0]}}/html/cross-origin-embedder-policy/resources/report.py?endpoint=endpoint" }] }, { "group": "report-only-endpoint", "max_age": 10886400, "endpoints": [{ "url": "https://{{hosts[][www]}}:{{ports[https][0]}}/html/cross-origin-embedder-policy/resources/report.py?endpoint=report-only-endpoint" }] }
...@@ -232,4 +232,28 @@ async_test(t => { ...@@ -232,4 +232,28 @@ async_test(t => {
document.body.append(frame); document.body.append(frame);
}, 'navigation CORP is checked with the parent frame, not the navigation source - to be blocked'); }, 'navigation CORP is checked with the parent frame, not the navigation source - to be blocked');
async_test(t => {
const bc = new BroadcastChannel(token());
let loaded = false;
bc.onmessage = t.step_func((event) => {
loaded = true;
});
t.step_timeout(() => {
// Make sure the iframe didn't load. See
// https://github.com/whatwg/html/issues/125 for why a timeout is used
// here. Long term all network error handling should be similar and have a
// reliable event.
assert_false(loaded);
t.done();
}, 2000);
const dest = `${HOST.ORIGIN}${BASE}/navigate-require-corp.sub.html?channelName=${bc.name}`;
const frame = document.createElement("iframe");
t.add_cleanup(() => frame.remove());
// |dest| is a same-origin URL and hence not blocked by CORP but reidirect.py
// is a cross-origin (actually cross-site) URL, so blocked by CORP.
frame.src = `${HOST.HTTPS_NOTSAMESITE_ORIGIN}/common/redirect.py?location=${encodeURIComponent(dest)}`;
document.body.append(frame);
}, 'navigation CORP is checked for each redirect');
</script> </script>
...@@ -9,11 +9,29 @@ def main(request, response): ...@@ -9,11 +9,29 @@ def main(request, response):
response.headers.set('Access-Control-Allow-Headers', 'content-type') response.headers.set('Access-Control-Allow-Headers', 'content-type')
return '' return ''
url_dir = '/'.join(request.url_parts.path.split('/')[:-1]) + '/' uuidMap = {
key = request.GET.first('key') 'endpoint': '01234567-0123-0123-0123-0123456789AB',
reports = request.server.stash.take(key, url_dir) or [] 'report-only-endpoint': '01234567-0123-0123-0123-0123456789CD'
for report in json.loads(request.body): }
reports.append(report)
request.server.stash.put(key, reports, url_dir)
response.headers.set('Access-Control-Allow-Origin', '*') response.headers.set('Access-Control-Allow-Origin', '*')
return 'done' endpoint = request.GET.first('endpoint')
if endpoint not in uuidMap:
response.status = 400
return 'invalid endpoint'
path = '/'.join(request.url_parts.path.split('/')[:-1]) + '/'
key = uuidMap[endpoint]
if request.method == 'POST':
reports = request.server.stash.take(key, path) or []
for report in json.loads(request.body):
reports.append(report)
request.server.stash.put(key, reports, path)
return 'done'
if request.method == 'GET':
return json.dumps(request.server.stash.take(key, path) or [])
response.status = 400
return 'invalid method'
cross-origin-embedder-policy: require-corp; report-to="endpoint"
cross-origin-embedder-policy-report-only: require-corp; report-to="report-only-endpoint";
from wptserve.handlers import json_handler
@json_handler
def main(request, response):
path = '/'.join(request.url_parts.path.split('/')[:-1]) + '/'
key = request.GET.first('key')
response.headers.set('Access-Control-Allow-Origin', '*')
return request.server.stash.take(key, path)
<!doctype html>
<html>
<script src="/common/get-host-info.sub.js"></script>
<script>
const HOST = get_host_info();
const current = new URL(window.location.href);
const token = current.searchParams.get("token");
const cache = 'no-store';
const mode = 'no-cors';
async function run() {
const init = { mode, cache };
// This is not blocked.
await fetch('/common/text-plain.txt', init);
// This is blocked but not due to COEP.
try {
await fetch('nothing-same-origin-corp.txt', init);
} catch (e) {
}
try {
await fetch(`${HOST.REMOTE_ORIGIN}/common/text-plain.txt`, init);
} catch (e) {
}
try {
await fetch(`/common/redirect.py?location=${HOST.REMOTE_ORIGIN}/common/text-plain.txt`, init);
} catch (e) {
}
}
run();
</script>
</html>
cache-control: no-store, no-cache
report-to: { "group": "endpoint", "max_age": 3600, "endpoints": [{ "url": "https://{{hosts[][www]}}:{{ports[https][0]}}/html/cross-origin-embedder-policy/resources/report.py?key={{GET[token1]}}" }] }, { "group": "report-only-endpoint", "max_age": 3600, "endpoints": [{ "url": "https://{{hosts[][www]}}:{{ports[https][0]}}/html/cross-origin-embedder-policy/resources/report.py?key={{GET[token2]}}" }] }
cross-origin-embedder-policy: require-corp; report-to="endpoint"
cross-origin-embedder-policy-report-only: require-corp; report-to="report-only-endpoint"
...@@ -4,9 +4,9 @@ https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolati ...@@ -4,9 +4,9 @@ https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolati
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=cross-origin: *loading finished* https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=cross-origin: *loading finished*
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=same-site: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-site https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=same-site: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-site
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php: net::ERR_BLOCKED_BY_RESPONSE coep-frame-resource-needs-coep-header https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin-after-defaulted-to-same-origin-by-coep
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin-after-defaulted-to-same-origin-by-coep https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin-after-defaulted-to-same-origin-by-coep
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-site: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-site https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-site: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-site
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php?coep&corp=same-origin: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin
https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php&coop: net::ERR_BLOCKED_BY_RESPONSE coep-frame-resource-needs-coep-header https://devtools.oopif.test:8443/inspector-protocol/network/cross-origin-isolation/resources/page-with-coep-corp.php&coop: net::ERR_BLOCKED_BY_RESPONSE corp-not-same-origin-after-defaulted-to-same-origin-by-coep
This is a testharness.js-based test.
PASS "none" top-level: navigating a frame to "none" should succeed
PASS "none" top-level: navigating a frame from "require-corp" to "none" should succeed
PASS "none" top-level: navigating a frame back from "require-corp" should succeed
PASS "require-corp" top-level noopener popup: navigating to "none" should succeed
PASS CORP: same-site is checked and allowed.
FAIL CORP: same-site is checked and blocked. assert_false: expected false got true
Harness: the test ran to completion.
This is a testharness.js-based test. This is a testharness.js-based test.
FAIL report-to parameter for COEP and COEP-report-only assert_not_equals: got disallowed value null FAIL subresource CORP assert_unreached: A report whose blocked-url is https://www1.web-platform.test:8444/common/text-plain.txt?abc&subresource-corp and url is https://web-platform.test:8444/html/cross-origin-embedder-policy/resources/reporting-empty-frame.html is not found. Reached unreachable code
FAIL navigation CORP assert_unreached: A report whose blocked-url is https://www1.web-platform.test:8444/common/blank.html?abc&navigation-corp and url is https://web-platform.test:8444/html/cross-origin-embedder-policy/resources/reporting-empty-frame.html is not found. Reached unreachable code
Harness: the test ran to completion. Harness: the test ran to completion.
...@@ -14,5 +14,6 @@ PASS CORP: same-site is checked and allowed. ...@@ -14,5 +14,6 @@ PASS CORP: same-site is checked and allowed.
FAIL CORP: same-site is checked and blocked. assert_false: expected false got true FAIL CORP: same-site is checked and blocked. assert_false: expected false got true
PASS navigation CORP is checked with the parent frame, not the navigation source - to be allowed PASS navigation CORP is checked with the parent frame, not the navigation source - to be allowed
PASS navigation CORP is checked with the parent frame, not the navigation source - to be blocked PASS navigation CORP is checked with the parent frame, not the navigation source - to be blocked
FAIL navigation CORP is checked for each redirect assert_false: expected false got true
Harness: the test ran to completion. Harness: the test ran to completion.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment