Commit 61acf77c authored by Mike West's avatar Mike West Committed by Commit Bot

Correctly support `Sec-Fetch-Mode` for `<portal>` requests.

Requests from `<portal>` elements currently send a `Sec-Fetch-Mode` of
`navigation`. They ought to send something more like
`nested-navigation`, which more accurately represents the request's
status vis-a-vis its requestor.

https://github.com/w3c/webappsec-fetch-metadata/issues/46

Bug: 1005143
Change-Id: Ib7f434ddf90d2e15b4bf139ab77c778a090251f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1819297Reviewed-by: default avatarLucas Gadani <lfg@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Auto-Submit: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699399}
parent 3843c441
...@@ -230,12 +230,19 @@ std::unique_ptr<network::ResourceRequest> CreateResourceRequest( ...@@ -230,12 +230,19 @@ std::unique_ptr<network::ResourceRequest> CreateResourceRequest(
new_request->has_user_gesture = request_info->common_params->has_user_gesture; new_request->has_user_gesture = request_info->common_params->has_user_gesture;
new_request->enable_load_timing = true; new_request->enable_load_timing = true;
FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id);
if (request_info->is_main_frame) { if (request_info->is_main_frame) {
new_request->mode = network::mojom::RequestMode::kNavigate; // `<portal>` acts like a top-level navigation, but we want to represent it
// as a nested navigation for the purposes of security checks like
// `Sec-Fetch-Mode`.
new_request->mode =
frame_tree_node &&
WebContentsImpl::FromFrameTreeNode(frame_tree_node)->IsPortal()
? network::mojom::RequestMode::kNavigateNestedFrame
: network::mojom::RequestMode::kNavigate;
} else { } else {
new_request->mode = network::mojom::RequestMode::kNavigateNestedFrame; new_request->mode = network::mojom::RequestMode::kNavigateNestedFrame;
FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id);
if (frame_tree_node && (frame_tree_node->frame_owner_element_type() == if (frame_tree_node && (frame_tree_node->frame_owner_element_type() ==
blink::FrameOwnerElementType::kObject || blink::FrameOwnerElementType::kObject ||
frame_tree_node->frame_owner_element_type() == frame_tree_node->frame_owner_element_type() ==
......
<!DOCTYPE html>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=/fetch/sec-metadata/resources/helper.js></script>
<script src=/common/utils.js></script>
<body>
<script>
const USER = true;
const FORCED = false;
function create_test(host, expectations) {
async_test(t => {
let p = document.createElement('portal');
p.addEventListener('message', t.step_func(e => {
assert_header_equals(e.data, expectations);
t.done();
}));
let url = `https://${host}/fetch/sec-metadata/resources/post-to-owner.py`;
p.src = url;
document.body.appendChild(p);
}, `{{host}} -> ${host} portal`);
}
create_test("{{host}}:{{ports[https][0]}}", {
// TODO(mkwst): 'document' seems right, I guess? Perhaps a portal-specific destination would be better?
"dest": "document",
"site": "same-origin",
"user": "",
"mode": "nested-navigate"
});
create_test("{{hosts[][www]}}:{{ports[https][0]}}", {
"dest": "document",
"site": "same-site",
"user": "",
"mode": "nested-navigate"
});
create_test("{{hosts[alt][www]}}:{{ports[https][0]}}", {
"dest": "document",
"site": "cross-site",
"user": "",
"mode": "nested-navigate"
});
</script>
...@@ -14,6 +14,8 @@ def main(request, response): ...@@ -14,6 +14,8 @@ def main(request, response):
window.opener.postMessage(data, "*"); window.opener.postMessage(data, "*");
if (window.top != window) if (window.top != window)
window.top.postMessage(data, "*"); window.top.postMessage(data, "*");
if (window.portalHost)
window.portalHost.postMessage(data, "*");
</script> </script>
""" % json.dumps({ """ % json.dumps({
"dest": request.headers.get("sec-fetch-dest", ""), "dest": request.headers.get("sec-fetch-dest", ""),
......
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