Commit 53455717 authored by Hayato Ito's avatar Hayato Ito Committed by Commit Bot

Add path restriction to WebBundle subresource loading

Add path restriction so that this matches the recent change [1] of the
explainer.

Subresource path restriction is:

> its [path](https://url.spec.whatwg.org/#concept-url-path) contains
> the bundle's path as a prefix,

Note that the explainer says "the bundle's path as a prefix", however,
this CL uses "the bundle's path *without a filename* as a prefix"
as subresource path restriction.

For example, if a bundle's URL is "https://foo.com/dir/foo.wbn",
a subresource's path should contain "dir/", instead of "dir/foo.wbn",
as a prefix.

We'll update the explainer to match the implementation.

- [1] https://github.com/WICG/webpackage/pull/601.

Bug: 1082020

Change-Id: I9c2d25108c4169310c395372ac8f7ae74c6a7325
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2460366
Commit-Queue: Hayato Ito <hayato@chromium.org>
Reviewed-by: default avatarKunihiko Sakamoto <ksakamoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815047}
parent fc5db120
......@@ -209,6 +209,14 @@ bool LinkWebBundle::CanHandleRequest(const KURL& url) const {
": bundled resource must be same origin with the bundle.");
return false;
}
if (!url.GetString().StartsWith(bundle_loader_->url().BaseAsString())) {
OnWebBundleError(
url.ElidedString() + " cannot be loaded from WebBundle " +
bundle_loader_->url().ElidedString() +
": bundled resource path must contain the bundle's path as a prefix.");
return false;
}
return true;
}
......
......@@ -22,28 +22,35 @@ gen-bundle \
gen-bundle \
-version b1 \
-baseURL $wpt_test_http_origin/ \
-primaryURL $wpt_test_http_origin/root.js \
-baseURL $wpt_test_http_origin/web-bundle/resources/wbn/ \
-primaryURL $wpt_test_http_origin/web-bundle/resources/wbn/root.js \
-dir subresource/ \
-o wbn/subresource.wbn
gen-bundle \
-version b1 \
-baseURL $wpt_test_http_origin/web-bundle/resources/dynamic/ \
-primaryURL $wpt_test_http_origin/web-bundle/resources/dynamic/resource1.js \
-baseURL $wpt_test_http_origin/web-bundle/resources/wbn/dynamic/ \
-primaryURL $wpt_test_http_origin/web-bundle/resources/wbn/dynamic/resource1.js \
-dir dynamic1/ \
-o wbn/dynamic1.wbn
gen-bundle \
-version b1 \
-baseURL $wpt_test_http_origin/web-bundle/resources/dynamic/ \
-primaryURL $wpt_test_http_origin/web-bundle/resources/dynamic/resource1.js \
-baseURL $wpt_test_http_origin/web-bundle/resources/wbn/dynamic/ \
-primaryURL $wpt_test_http_origin/web-bundle/resources/wbn/dynamic/resource1.js \
-dir dynamic2/ \
-o wbn/dynamic2.wbn
gen-bundle \
-version b1 \
-baseURL $wpt_test_https_origin/web-bundle/resources/dynamic/ \
-primaryURL $wpt_test_https_origin/web-bundle/resources/dynamic/resource1.js \
-baseURL $wpt_test_https_origin/web-bundle/resources/wbn/dynamic/ \
-primaryURL $wpt_test_https_origin/web-bundle/resources/wbn/dynamic/resource1.js \
-dir dynamic1/ \
-o wbn/dynamic1-crossorigin.wbn
gen-bundle \
-version b1 \
-baseURL $wpt_test_https_origin/web-bundle/resources/path-restriction/ \
-primaryURL $wpt_test_https_origin/web-bundle/resources/path-restriction/resource1.js \
-dir path-restriction1/ \
-o wbn/path-restriction.wbn
......@@ -8,22 +8,23 @@
<script src="/resources/testharnessreport.js"></script>
<body>
<link id="link-web-bundle" rel="webbundle" href="../resources/wbn/subresource.wbn"
resources="http://web-platform.test:8001/root.js http://web-platform.test:8001/submodule.js" />
resources="http://web-platform.test:8001/web-bundle/resources/wbn/root.js
http://web-platform.test:8001/web-bundle/resources/wbn/submodule.js" />
<script>
promise_test(async () => {
const module = await import('http://web-platform.test:8001/root.js');
const module = await import('http://web-platform.test:8001/web-bundle/resources/wbn/root.js');
assert_equals(module.result, 'OK');
}, "Subresource loading with WebBundle");
promise_test(async () => {
const response = await fetch('http://web-platform.test:8001/root.js');
const response = await fetch('http://web-platform.test:8001/web-bundle/resources/wbn/root.js');
const text = await response.text();
assert_equals(text, "export * from './submodule.js';\n");
}, "Subresource loading with WebBundle (Fetch API)");
promise_test(t => {
const url =
'/common/redirect.py?location=http://web-platform.test:8001/root.js';
'/common/redirect.py?location=http://web-platform.test:8001/web-bundle/resources/wbn/root.js';
return promise_rejects_js(t, TypeError, import(url));
}, "Subresource loading with WebBundle shouldn't affect redirect");
......@@ -31,35 +32,35 @@
const link = document.createElement("link");
link.rel = "webbundle";
link.href = "../resources/wbn/dynamic1.wbn";
link.resources.add('http://web-platform.test:8001/web-bundle/resources/dynamic/resource1.js',
'http://web-platform.test:8001/web-bundle/resources/dynamic/resource2.js',
'http://web-platform.test:8001/web-bundle/resources/dynamic/resource4.js');
link.resources.add('http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/resource1.js',
'http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/resource2.js',
'http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/resource4.js');
document.body.appendChild(link);
const module = await import('http://web-platform.test:8001/web-bundle/resources/dynamic/resource1.js');
const module = await import('http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/resource1.js');
assert_equals(module.result, 'resource1 from dynamic1.wbn');
link.href = "../resources/wbn/dynamic2.wbn";
const module2 = await import('http://web-platform.test:8001/web-bundle/resources/dynamic/resource2.js');
const module2 = await import('http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/resource2.js');
assert_equals(module2.result, 'resource2 from dynamic2.wbn');
// A resource not specified in the resources attribute, but in the bundle.
const module3 = await import('http://web-platform.test:8001/web-bundle/resources/dynamic/resource3.js');
const module3 = await import('http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/resource3.js');
assert_equals(module3.result, 'resource3 from network');
document.body.removeChild(link);
const module4 = await import('http://web-platform.test:8001/web-bundle/resources/dynamic/resource4.js');
const module4 = await import('http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/resource4.js');
assert_equals(module4.result, 'resource4 from network');
// Module scripts are stored to the Document's module map once loaded.
// So import()ing the same module script will reuse the previously loaded
// script.
const module_second = await import('http://web-platform.test:8001/web-bundle/resources/dynamic/resource1.js');
const module_second = await import('http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/resource1.js');
assert_equals(module_second.result, 'resource1 from dynamic1.wbn');
}, 'Dynamically adding / updating / removing "<link rel=webbundle>"');
promise_test(async () => {
const classic_script_url = 'http://web-platform.test:8001/web-bundle/resources/dynamic/classic_script.js';
const classic_script_url = 'http://web-platform.test:8001/web-bundle/resources/wbn/dynamic/classic_script.js';
const link = document.createElement("link");
link.rel = "webbundle";
link.href = "../resources/wbn/dynamic1.wbn";
......@@ -93,15 +94,25 @@
const link = document.createElement('link');
link.rel = 'webbundle';
link.href = '../resources/wbn/dynamic1-crossorigin.wbn';
link.resources = 'https://web-platform.test:8444/web-bundle/resources/dynamic/resource1.js';
link.resources = 'https://web-platform.test:8444/web-bundle/resources/wbn/dynamic/resource1.js';
document.body.appendChild(link);
const module = await import(link.resources);
assert_equals(module.result, 'resource1 from network');
}, 'Subresource URL must be same-origin with bundle URL');
promise_test(async () => {
const link = document.createElement('link');
link.rel = 'webbundle';
link.href = '../resources/wbn/path-restricion.wbn';
link.resources = 'http://web-platform.test:8001/web-bundle/resources/path-restriction/resource1.js';
document.body.appendChild(link);
const module = await import(link.resources);
assert_equals(module.result, 'resource1 from network');
}, "Subresource path contains the bundle's path (without a filename) as a prefix");
promise_test(async () => {
const wbn_url = 'http://web-platform.test:8001/web-bundle/resources/wbn/subresource.wbn?test-resources-update';
const resource_url = 'http://web-platform.test:8001/submodule.js';
const resource_url = 'http://web-platform.test:8001/web-bundle/resources/wbn/submodule.js';
const link = await addLinkAndWaitForLoad(wbn_url);
link.resources.add(resource_url);
const resp = await fetch(resource_url, {cache: 'no-store'});
......
......@@ -24,7 +24,7 @@ promise_test(async (t) => {
'Subresource Web Bundles should be supported.');
const wbn_url = 'https://localhost:8443/loading/wbn/resources/wbn/wbn-subresource-origin-trial.wbn';
const script_url = 'https://localhost:8443/loading/wbn/resources/server/wbn-subresource-origin-trial/script.js';
const script_url = 'https://localhost:8443/loading/wbn/resources/wbn/server/wbn-subresource-origin-trial/script.js';
const SubresourceWebBundles = 3446; // From web_feature.mojom
assert_false(window.internals.isUseCounted(document, SubresourceWebBundles));
......
......@@ -26,7 +26,7 @@ promise_test(async (t) => {
'Subresource Web Bundles should be supported.');
const wbn_url = 'https://localhost:8443/loading/wbn/resources/wbn/wbn-subresource-third-party-origin-trial.wbn';
const script_url = 'https://localhost:8443/loading/wbn/resources/server/wbn-subresource-third-party-origin-trial/script.js';
const script_url = 'https://localhost:8443/loading/wbn/resources/wbn/server/wbn-subresource-third-party-origin-trial/script.js';
const SubresourceWebBundles = 3446; // From web_feature.mojom
assert_false(window.internals.isUseCounted(document, SubresourceWebBundles));
......
......@@ -14,21 +14,21 @@ fi
gen-bundle \
-version b1 \
-baseURL http://127.0.0.1:8000/loading/wbn/resources/server/hello/ \
-primaryURL http://127.0.0.1:8000/loading/wbn/resources/server/hello/script.js \
-baseURL http://127.0.0.1:8000/loading/wbn/resources/wbn/server/hello/ \
-primaryURL http://127.0.0.1:8000/loading/wbn/resources/wbn/server/hello/script.js \
-dir hello/ \
-o wbn/hello.wbn
gen-bundle \
-version b1 \
-baseURL https://localhost:8443/loading/wbn/resources/server/wbn-subresource-origin-trial/ \
-primaryURL https://localhost:8443/loading/wbn/resources/server/wbn-subresource-origin-trial/script.js \
-baseURL https://localhost:8443/loading/wbn/resources/wbn/server/wbn-subresource-origin-trial/ \
-primaryURL https://localhost:8443/loading/wbn/resources/wbn/server/wbn-subresource-origin-trial/script.js \
-dir wbn-subresource-origin-trial/ \
-o wbn/wbn-subresource-origin-trial.wbn
gen-bundle \
-version b1 \
-baseURL https://localhost:8443/loading/wbn/resources/server/wbn-subresource-third-party-origin-trial/ \
-primaryURL https://localhost:8443/loading/wbn/resources/server/wbn-subresource-third-party-origin-trial/script.js \
-baseURL https://localhost:8443/loading/wbn/resources/wbn/server/wbn-subresource-third-party-origin-trial/ \
-primaryURL https://localhost:8443/loading/wbn/resources/wbn/server/wbn-subresource-third-party-origin-trial/script.js \
-dir wbn-subresource-third-party-origin-trial/ \
-o wbn/wbn-subresource-third-party-origin-trial.wbn
......@@ -6,5 +6,5 @@ main frame - didFinishDocumentLoadForFrame
main frame - didHandleOnloadEventsForFrame
main frame - didFinishLoadForFrame
CONSOLE MESSAGE: line 1: Hello from WebBundle
CONSOLE WARNING: http://127.0.0.1:8000/loading/wbn/resources/wbn/hello.wbn: http://127.0.0.1:8000/loading/wbn/resources/server/hello/notfound.js is not found in the WebBundle.
CONSOLE WARNING: http://127.0.0.1:8000/loading/wbn/resources/wbn/hello.wbn: http://127.0.0.1:8000/loading/wbn/resources/wbn/server/hello/notfound.js is not found in the WebBundle.
......@@ -2,8 +2,8 @@
<head>
<title>Subresource loading with Web Bundles</title>
<link rel="webbundle" href="../resources/wbn/hello.wbn"
resources="http://127.0.0.1:8000/loading/wbn/resources/server/hello/script.js
http://127.0.0.1:8000/loading/wbn/resources/server/hello/notfound.js">
resources="http://127.0.0.1:8000/loading/wbn/resources/wbn/server/hello/script.js
http://127.0.0.1:8000/loading/wbn/resources/wbn/server/hello/notfound.js">
</head>
<body>
<script>
......@@ -27,7 +27,7 @@ if (!document.createElement('link').relList.supports('webbundle')) {
await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'http://127.0.0.1:8000/loading/wbn/resources/server/hello/script.js';
script.src = 'http://127.0.0.1:8000/loading/wbn/resources/wbn/server/hello/script.js';
script.onload = resolve;
script.onerror = reject;
document.body.appendChild(script);
......@@ -36,7 +36,7 @@ await new Promise((resolve, reject) => {
await new Promise((resolve, reject) => {
// This request should fail rather than be loaded from the network.
const script = document.createElement('script');
script.src = 'http://127.0.0.1:8000/loading/wbn/resources/server/hello/notfound.js';
script.src = 'http://127.0.0.1:8000/loading/wbn/resources/wbn/server/hello/notfound.js';
script.onload = reject;
script.onerror = resolve;
document.body.appendChild(script);
......
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