Commit d252a108 authored by Kunihiko Sakamoto's avatar Kunihiko Sakamoto Committed by Commit Bot

Subresource WebBundles: Same-origin restriction

This patch restricts subresource loading from WebBundles only to
same-origin resources, i.e. origin of subresource URL must be
same-origin with the origin of the enclosing WebBundle's URL.

Bug: 11202527
Change-Id: Ic999c4582385560f22a1251c37bd3572f0ffd2bb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2368618Reviewed-by: default avatarTsuyoshi Horo <horo@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarHayato Ito <hayato@chromium.org>
Commit-Queue: Kunihiko Sakamoto <ksakamoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800907}
parent c5f21dfd
......@@ -28,7 +28,8 @@ class WebBundleLoader : public GarbageCollected<WebBundleLoader>,
const KURL& url)
: link_web_bundle_(&link_web_bundle),
pending_factory_receiver_(loader_factory_.BindNewPipeAndPassReceiver()),
url_(url) {
url_(url),
security_origin_(SecurityOrigin::Create(url)) {
ResourceRequest request(url);
request.SetUseStreamOnResponse(true);
// TODO(crbug.com/1082020): Revisit these once the fetch and process the
......@@ -84,6 +85,9 @@ class WebBundleLoader : public GarbageCollected<WebBundleLoader>,
void DidFailRedirectCheck() override { DidFailInternal(); }
const KURL& url() const { return url_; }
scoped_refptr<SecurityOrigin> GetSecurityOrigin() const {
return security_origin_;
}
private:
void DidFailInternal() {
......@@ -113,6 +117,7 @@ class WebBundleLoader : public GarbageCollected<WebBundleLoader>,
pending_factory_receiver_;
bool failed_ = false;
KURL url_;
scoped_refptr<SecurityOrigin> security_origin_;
};
LinkWebBundle::LinkWebBundle(HTMLLinkElement* owner) : LinkResource(owner) {
......@@ -132,7 +137,7 @@ void LinkWebBundle::NotifyLoaded() {
owner_->ScheduleEvent();
}
void LinkWebBundle::OnWebBundleError(const String& message) {
void LinkWebBundle::OnWebBundleError(const String& message) const {
if (!owner_)
return;
ExecutionContext* context = owner_->GetDocument().GetExecutionContext();
......@@ -180,7 +185,17 @@ void LinkWebBundle::OwnerRemoved() {
}
bool LinkWebBundle::CanHandleRequest(const KURL& url) const {
return owner_ && owner_->ValidResourceUrls().Contains(url);
if (!owner_ || !owner_->ValidResourceUrls().Contains(url))
return false;
DCHECK(bundle_loader_);
if (!bundle_loader_->GetSecurityOrigin()->IsSameOriginWith(
SecurityOrigin::Create(url).get())) {
OnWebBundleError(url.ElidedString() + " cannot be loaded from WebBundle " +
bundle_loader_->url().ElidedString() +
": bundled resource must be same origin with the bundle.");
return false;
}
return true;
}
mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
......
......@@ -31,7 +31,7 @@ class CORE_EXPORT LinkWebBundle final : public LinkResource,
void Trace(Visitor* visitor) const override;
void NotifyLoaded();
void OnWebBundleError(const String& message);
void OnWebBundleError(const String& message) const;
// LinkResource overrides:
void Process() override;
......
......@@ -22,8 +22,8 @@ gen-bundle \
gen-bundle \
-version b1 \
-baseURL https://subresource-wbn.example/ \
-primaryURL https://subresource-wbn.example/root.js \
-baseURL $wpt_test_http_origin/ \
-primaryURL $wpt_test_http_origin/root.js \
-dir subresource/ \
-o wbn/subresource.wbn
......@@ -40,3 +40,10 @@ gen-bundle \
-primaryURL $wpt_test_http_origin/web-bundle/resources/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 \
-dir dynamic1/ \
-o wbn/dynamic1-crossorigin.wbn
......@@ -8,10 +8,10 @@
<script src="/resources/testharnessreport.js"></script>
<body>
<link id="link-web-bundle" rel="webbundle" href="../resources/wbn/subresource.wbn"
resources="https://subresource-wbn.example/root.js https://subresource-wbn.example/submodule.js" />
resources="http://web-platform.test:8001/root.js http://web-platform.test:8001/submodule.js" />
<script>
promise_test(async () => {
const module = await import('https://subresource-wbn.example/root.js');
const module = await import('http://web-platform.test:8001/root.js');
assert_equals(module.result, 'OK');
}, "Subresource loading with WebBundle");
......@@ -48,9 +48,19 @@
return addLinkAndWaitForError("../resources/wbn/nonexistent.wbn");
}, '<link rel="webbundle"> fires an error event on load failure');
promise_test(async () => {
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';
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 wbn_url = 'http://web-platform.test:8001/web-bundle/resources/wbn/subresource.wbn?test-resources-update';
const resource_url = 'https://subresource-wbn.example/submodule.js';
const resource_url = 'http://web-platform.test:8001/submodule.js';
const link = await addLinkAndWaitForLoad(wbn_url);
link.resources.add(resource_url);
const resp = await fetch(resource_url, {cache: 'no-store'});
......
<FilesMatch "\.wbn$">
# Allow bundles to be fetched via CORS.
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
......@@ -23,7 +23,7 @@ promise_test(async (t) => {
document.createElement('link').relList.supports('webbundle'),
'Subresource Web Bundles should be supported.');
const wbn_url = 'https://127.0.0.1:8443/loading/wbn/resources/wbn/wbn-subresource-origin-trial.wbn';
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 SubresourceWebBundles = 3446; // From web_feature.mojom
......
......@@ -25,7 +25,7 @@ promise_test(async (t) => {
document.createElement('link').relList.supports('webbundle'),
'Subresource Web Bundles should be supported.');
const wbn_url = 'https://127.0.0.1:8443/loading/wbn/resources/wbn/wbn-subresource-third-party-origin-trial.wbn';
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 SubresourceWebBundles = 3446; // From web_feature.mojom
......
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