Bug 1834864 - Select BCG more consistently during COOP+COEP process switches, r=smaug,tabbrowser-reviewers,mak
Previously it was possible to bypass specific BCG selection based on cross-origin isolated status if the site was allowed to load file URIs using enterprise policies, which could lead to a crash. This patch changes the behaviour such that BCG selection now happens correctly. The site will still not be cross-origin isolated due to being loaded into a file content process. Differential Revision: https://phabricator.services.mozilla.com/D217007
This commit is contained in:
@@ -202,6 +202,10 @@ skip-if = ["verify && os == 'mac'"]
|
|||||||
|
|
||||||
["browser_new_file_whitelisted_http_tab.js"]
|
["browser_new_file_whitelisted_http_tab.js"]
|
||||||
https_first_disabled = true
|
https_first_disabled = true
|
||||||
|
support-files = [
|
||||||
|
"file_coop_coep.html",
|
||||||
|
"file_coop_coep.html^headers^",
|
||||||
|
]
|
||||||
|
|
||||||
["browser_new_tab_bookmarks_toolbar_height.js"]
|
["browser_new_tab_bookmarks_toolbar_height.js"]
|
||||||
skip-if = ["!verify && os == 'mac'"] # Bug 1872477
|
skip-if = ["!verify && os == 'mac'"] # Bug 1872477
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
|
||||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
const TEST_HTTP_DOMAIN = "https://example.org/";
|
||||||
const TEST_HTTP = "http://example.org/";
|
|
||||||
|
const TEST_ROOT = getRootDirectory(gTestPath).replace(
|
||||||
|
"chrome://mochitests/content",
|
||||||
|
"https://example.org"
|
||||||
|
);
|
||||||
|
|
||||||
|
const TEST_NORMAL = `${TEST_ROOT}dummy_page.html`;
|
||||||
|
const TEST_COOP_COEP = `${TEST_ROOT}file_coop_coep.html`;
|
||||||
|
|
||||||
// Test for bug 1378377.
|
// Test for bug 1378377.
|
||||||
add_task(async function () {
|
add_task(async function () {
|
||||||
@@ -11,27 +18,72 @@ add_task(async function () {
|
|||||||
set: [["browser.tabs.remote.separateFileUriProcess", true]],
|
set: [["browser.tabs.remote.separateFileUriProcess", true]],
|
||||||
});
|
});
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(TEST_HTTP, async function (fileBrowser) {
|
await BrowserTestUtils.withNewTab(TEST_NORMAL, async function (fileBrowser) {
|
||||||
ok(
|
ok(
|
||||||
E10SUtils.isWebRemoteType(fileBrowser.remoteType),
|
E10SUtils.isWebRemoteType(fileBrowser.remoteType),
|
||||||
"Check that tab normally has web remote type."
|
"Check that tab normally has web remote type."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await SpecialPowers.spawn(fileBrowser, [], () => {
|
||||||
|
ok(
|
||||||
|
!content.crossOriginIsolated,
|
||||||
|
"Tab content is not cross-origin isolated"
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await BrowserTestUtils.withNewTab(
|
||||||
|
TEST_COOP_COEP,
|
||||||
|
async function (fileBrowser) {
|
||||||
|
ok(
|
||||||
|
fileBrowser.remoteType.startsWith(
|
||||||
|
E10SUtils.WEB_REMOTE_COOP_COEP_TYPE_PREFIX
|
||||||
|
),
|
||||||
|
"Check that COOP+COEP tab normally has webCOOP+COEP remote type."
|
||||||
|
);
|
||||||
|
await SpecialPowers.spawn(fileBrowser, [], () => {
|
||||||
|
ok(content.crossOriginIsolated, "Tab content is cross-origin isolated");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Set prefs to whitelist TEST_HTTP for file:// URI use.
|
// Set prefs to whitelist TEST_HTTP for file:// URI use.
|
||||||
await SpecialPowers.pushPrefEnv({
|
await SpecialPowers.pushPrefEnv({
|
||||||
set: [
|
set: [
|
||||||
["capability.policy.policynames", "allowFileURI"],
|
["capability.policy.policynames", "allowFileURI"],
|
||||||
["capability.policy.allowFileURI.sites", TEST_HTTP],
|
["capability.policy.allowFileURI.sites", TEST_HTTP_DOMAIN],
|
||||||
["capability.policy.allowFileURI.checkloaduri.enabled", "allAccess"],
|
["capability.policy.allowFileURI.checkloaduri.enabled", "allAccess"],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(TEST_HTTP, async function (fileBrowser) {
|
await BrowserTestUtils.withNewTab(TEST_NORMAL, async function (fileBrowser) {
|
||||||
is(
|
is(
|
||||||
fileBrowser.remoteType,
|
fileBrowser.remoteType,
|
||||||
E10SUtils.FILE_REMOTE_TYPE,
|
E10SUtils.FILE_REMOTE_TYPE,
|
||||||
"Check that tab now has file remote type."
|
"Check that tab now has file remote type."
|
||||||
);
|
);
|
||||||
|
await SpecialPowers.spawn(fileBrowser, [], () => {
|
||||||
|
ok(
|
||||||
|
!content.crossOriginIsolated,
|
||||||
|
"Tab content is not cross-origin isolated"
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await BrowserTestUtils.withNewTab(
|
||||||
|
TEST_COOP_COEP,
|
||||||
|
async function (fileBrowser) {
|
||||||
|
is(
|
||||||
|
fileBrowser.remoteType,
|
||||||
|
E10SUtils.FILE_REMOTE_TYPE,
|
||||||
|
"Check that tab now has file remote type."
|
||||||
|
);
|
||||||
|
await SpecialPowers.spawn(fileBrowser, [], () => {
|
||||||
|
ok(
|
||||||
|
!content.crossOriginIsolated,
|
||||||
|
"Tab content is not cross-origin isolated"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Cross-Origin-Opener-Policy: same-origin
|
||||||
|
Cross-Origin-Embedder-Policy: require-corp
|
||||||
@@ -2172,11 +2172,13 @@ CanonicalBrowsingContext::ChangeRemoteness(
|
|||||||
new PendingRemotenessChange(this, promise, aPendingSwitchId, aOptions);
|
new PendingRemotenessChange(this, promise, aPendingSwitchId, aOptions);
|
||||||
mPendingRemotenessChange = change;
|
mPendingRemotenessChange = change;
|
||||||
|
|
||||||
// If a specific BrowsingContextGroup ID was specified for this load, make
|
// If we're replacing BrowsingContext, determine which BrowsingContextGroup
|
||||||
// sure to keep it alive until the process switch is completed.
|
// we'll switch into, taking into account load options.
|
||||||
if (aOptions.mSpecificGroupId) {
|
if (aOptions.mReplaceBrowsingContext) {
|
||||||
change->mSpecificGroup =
|
change->mSpecificGroup =
|
||||||
BrowsingContextGroup::GetOrCreate(aOptions.mSpecificGroupId);
|
aOptions.mSpecificGroupId
|
||||||
|
? BrowsingContextGroup::GetOrCreate(aOptions.mSpecificGroupId)
|
||||||
|
: BrowsingContextGroup::Create(aOptions.mShouldCrossOriginIsolate);
|
||||||
change->mSpecificGroup->AddKeepAlive();
|
change->mSpecificGroup->AddKeepAlive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -418,6 +418,24 @@ static already_AddRefed<BasePrincipal> GetAboutReaderURLPrincipal(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the Cross-Origin-Opener-Policy of the given channel or ancestor
|
||||||
|
* BrowsingContext, checking if the response should be cross-origin isolated.
|
||||||
|
*/
|
||||||
|
static bool ShouldCrossOriginIsolate(nsIChannel* aChannel,
|
||||||
|
WindowGlobalParent* aParentWindow) {
|
||||||
|
nsILoadInfo::CrossOriginOpenerPolicy coop =
|
||||||
|
nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
|
||||||
|
if (aParentWindow) {
|
||||||
|
coop = aParentWindow->BrowsingContext()->Top()->GetOpenerPolicy();
|
||||||
|
} else if (nsCOMPtr<nsIHttpChannelInternal> httpChannel =
|
||||||
|
do_QueryInterface(aChannel)) {
|
||||||
|
MOZ_ALWAYS_SUCCEEDS(httpChannel->GetCrossOriginOpenerPolicy(&coop));
|
||||||
|
}
|
||||||
|
return coop ==
|
||||||
|
nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if loads for this site should be isolated on a per-site basis.
|
* Returns `true` if loads for this site should be isolated on a per-site basis.
|
||||||
* If `aTopBC` is nullptr, this is being called to check if a shared or service
|
* If `aTopBC` is nullptr, this is being called to check if a shared or service
|
||||||
@@ -580,6 +598,8 @@ Result<NavigationIsolationOptions, nsresult> IsolationOptionsForNavigation(
|
|||||||
|
|
||||||
NavigationIsolationOptions options;
|
NavigationIsolationOptions options;
|
||||||
options.mReplaceBrowsingContext = aHasCOOPMismatch;
|
options.mReplaceBrowsingContext = aHasCOOPMismatch;
|
||||||
|
options.mShouldCrossOriginIsolate =
|
||||||
|
ShouldCrossOriginIsolate(aChannel, aParentWindow);
|
||||||
|
|
||||||
// Check if this load has an explicit remote type override. This is used to
|
// Check if this load has an explicit remote type override. This is used to
|
||||||
// perform an about:blank load within a specific content process.
|
// perform an about:blank load within a specific content process.
|
||||||
@@ -871,28 +891,9 @@ Result<NavigationIsolationOptions, nsresult> IsolationOptionsForNavigation(
|
|||||||
webProcessType = WebProcessType::WebIsolated;
|
webProcessType = WebProcessType::WebIsolated;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we should be loading in a webCOOP+COEP remote type due to our COOP
|
// Check if we should be cross-origin isolated.
|
||||||
// status.
|
if (options.mShouldCrossOriginIsolate) {
|
||||||
nsILoadInfo::CrossOriginOpenerPolicy coop =
|
|
||||||
nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
|
|
||||||
if (aParentWindow) {
|
|
||||||
coop = aTopBC->GetOpenerPolicy();
|
|
||||||
} else if (nsCOMPtr<nsIHttpChannelInternal> httpChannel =
|
|
||||||
do_QueryInterface(aChannel)) {
|
|
||||||
MOZ_ALWAYS_SUCCEEDS(httpChannel->GetCrossOriginOpenerPolicy(&coop));
|
|
||||||
}
|
|
||||||
if (coop ==
|
|
||||||
nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP) {
|
|
||||||
webProcessType = WebProcessType::WebCoopCoep;
|
webProcessType = WebProcessType::WebCoopCoep;
|
||||||
|
|
||||||
// If we're changing BrowsingContext, and are going to end up within a
|
|
||||||
// webCOOP+COEP group, ensure we use a cross-origin isolated BCG ID.
|
|
||||||
if (options.mReplaceBrowsingContext) {
|
|
||||||
MOZ_ASSERT(!options.mSpecificGroupId,
|
|
||||||
"overriding previously-specified BCG ID");
|
|
||||||
options.mSpecificGroupId = BrowsingContextGroup::CreateId(
|
|
||||||
/* aPotentiallyCrossOriginIsolated */ true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (webProcessType) {
|
switch (webProcessType) {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ struct NavigationIsolationOptions {
|
|||||||
nsCString mRemoteType;
|
nsCString mRemoteType;
|
||||||
bool mReplaceBrowsingContext = false;
|
bool mReplaceBrowsingContext = false;
|
||||||
uint64_t mSpecificGroupId = 0;
|
uint64_t mSpecificGroupId = 0;
|
||||||
|
bool mShouldCrossOriginIsolate = false;
|
||||||
bool mTryUseBFCache = false;
|
bool mTryUseBFCache = false;
|
||||||
RefPtr<SessionHistoryEntry> mActiveSessionHistoryEntry;
|
RefPtr<SessionHistoryEntry> mActiveSessionHistoryEntry;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user