зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1543786 - Ensure that we revoke a top frame's storage access when it is navigated away; r=baku
Differential Revision: https://phabricator.services.mozilla.com/D27155 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
b3529e64b7
Коммит
0ad9b25d34
|
@ -2669,8 +2669,8 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
|
||||||
RecomputeCanExecuteScripts();
|
RecomputeCanExecuteScripts();
|
||||||
|
|
||||||
// Inform windows when they're being removed from their parent.
|
// Inform windows when they're being removed from their parent.
|
||||||
if (!aParent && mScriptGlobal) {
|
if (!aParent) {
|
||||||
mScriptGlobal->ParentWindowChanged();
|
MaybeClearStorageAccessFlag();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(mInheritPrivateBrowsingId || wasPrivate == UsePrivateBrowsing(),
|
NS_ASSERTION(mInheritPrivateBrowsingId || wasPrivate == UsePrivateBrowsing(),
|
||||||
|
@ -2679,6 +2679,22 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsDocShell::MaybeClearStorageAccessFlag() {
|
||||||
|
if (mScriptGlobal) {
|
||||||
|
// Tell our window that the parent has now changed.
|
||||||
|
mScriptGlobal->ParentWindowChanged();
|
||||||
|
|
||||||
|
// Tell all of our children about the change recursively as well.
|
||||||
|
nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList);
|
||||||
|
while (iter.HasMore()) {
|
||||||
|
nsCOMPtr<nsIDocShell> child = do_QueryObject(iter.GetNext());
|
||||||
|
if (child) {
|
||||||
|
static_cast<nsDocShell*>(child.get())->MaybeClearStorageAccessFlag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocShell::GetSameTypeParent(nsIDocShellTreeItem** aParent) {
|
nsDocShell::GetSameTypeParent(nsIDocShellTreeItem** aParent) {
|
||||||
NS_ENSURE_ARG_POINTER(aParent);
|
NS_ENSURE_ARG_POINTER(aParent);
|
||||||
|
|
|
@ -401,6 +401,9 @@ class nsDocShell final : public nsDocLoader,
|
||||||
nsresult InternalLoad(nsDocShellLoadState* aLoadState,
|
nsresult InternalLoad(nsDocShellLoadState* aLoadState,
|
||||||
nsIDocShell** aDocShell, nsIRequest** aRequest);
|
nsIDocShell** aDocShell, nsIRequest** aRequest);
|
||||||
|
|
||||||
|
// Clear the document's storage access flag if needed.
|
||||||
|
void MaybeClearStorageAccessFlag();
|
||||||
|
|
||||||
private: // member functions
|
private: // member functions
|
||||||
friend class nsDSURIContentListener;
|
friend class nsDSURIContentListener;
|
||||||
friend class FramingChecker;
|
friend class FramingChecker;
|
||||||
|
|
|
@ -577,6 +577,12 @@ nsresult nsFrameLoader::ReallyStartLoadingInternal() {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetDocShell()) {
|
||||||
|
// If we already have a docshell, ensure that the docshell's storage access
|
||||||
|
// flag is cleared.
|
||||||
|
GetDocShell()->MaybeClearStorageAccessFlag();
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = MaybeCreateDocShell();
|
nsresult rv = MaybeCreateDocShell();
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1108,6 +1114,8 @@ void nsFrameLoader::Hide() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetDocShell()->MaybeClearStorageAccessFlag();
|
||||||
|
|
||||||
nsCOMPtr<nsIContentViewer> contentViewer;
|
nsCOMPtr<nsIContentViewer> contentViewer;
|
||||||
GetDocShell()->GetContentViewer(getter_AddRefs(contentViewer));
|
GetDocShell()->GetContentViewer(getter_AddRefs(contentViewer));
|
||||||
if (contentViewer) contentViewer->SetSticky(false);
|
if (contentViewer) contentViewer->SetSticky(false);
|
||||||
|
|
|
@ -1052,14 +1052,19 @@ mozilla::ipc::IPCResult TabChild::RecvLoadURL(const nsCString& aURI,
|
||||||
nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
|
nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
|
||||||
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
|
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
|
||||||
|
|
||||||
nsresult rv =
|
nsIWebNavigation* webNav = WebNavigation();
|
||||||
WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(aURI), loadURIOptions);
|
nsresult rv = webNav->LoadURI(NS_ConvertUTF8toUTF16(aURI), loadURIOptions);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_WARNING(
|
NS_WARNING(
|
||||||
"WebNavigation()->LoadURI failed. Eating exception, what else can I "
|
"WebNavigation()->LoadURI failed. Eating exception, what else can I "
|
||||||
"do?");
|
"do?");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
|
||||||
|
if (docShell) {
|
||||||
|
nsDocShell::Cast(docShell)->MaybeClearStorageAccessFlag();
|
||||||
|
}
|
||||||
|
|
||||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, aURI);
|
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, aURI);
|
||||||
|
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
|
|
|
@ -335,7 +335,7 @@ this.AntiTracking = {
|
||||||
} else {
|
} else {
|
||||||
thirdPartyPage = TEST_3RD_PARTY_PAGE;
|
thirdPartyPage = TEST_3RD_PARTY_PAGE;
|
||||||
}
|
}
|
||||||
await ContentTask.spawn(browser,
|
let id = await ContentTask.spawn(browser,
|
||||||
{ page: thirdPartyPage,
|
{ page: thirdPartyPage,
|
||||||
nextPage: TEST_4TH_PARTY_PAGE,
|
nextPage: TEST_4TH_PARTY_PAGE,
|
||||||
callback: options.callback.toString(),
|
callback: options.callback.toString(),
|
||||||
|
@ -420,14 +420,57 @@ this.AntiTracking = {
|
||||||
|
|
||||||
ifr.src = obj.nextPage;
|
ifr.src = obj.nextPage;
|
||||||
});
|
});
|
||||||
|
case "navigate-topframe":
|
||||||
|
// pass-through
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ok(false, "Unexpected accessRemoval code passed: " + obj.accessRemoval);
|
ok(false, "Unexpected accessRemoval code passed: " + obj.accessRemoval);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (doAccessRemovalChecks &&
|
||||||
|
options.accessRemoval == "navigate-topframe") {
|
||||||
|
await BrowserTestUtils.loadURI(browser, TEST_4TH_PARTY_PAGE);
|
||||||
|
await BrowserTestUtils.browserLoaded(browser);
|
||||||
|
|
||||||
|
let pageshow = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow");
|
||||||
|
gBrowser.goBack();
|
||||||
|
await pageshow;
|
||||||
|
|
||||||
|
await ContentTask.spawn(browser,
|
||||||
|
{ id,
|
||||||
|
callbackAfterRemoval: options.callbackAfterRemoval ?
|
||||||
|
options.callbackAfterRemoval.toString() : null,
|
||||||
|
},
|
||||||
|
async function(obj) {
|
||||||
|
let ifr = content.document.getElementById(obj.id);
|
||||||
|
ifr.contentWindow.postMessage(obj.callbackAfterRemoval, "*");
|
||||||
|
|
||||||
|
content.addEventListener("message", function msg(event) {
|
||||||
|
if (event.data.type == "finish") {
|
||||||
|
content.removeEventListener("message", msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.data.type == "ok") {
|
||||||
|
ok(event.data.what, event.data.msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.data.type == "info") {
|
||||||
|
info(event.data.msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(false, "Unknown message");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (options.allowList) {
|
if (options.allowList) {
|
||||||
info("Enabling content blocking for this page");
|
info("Enabling content blocking for this page");
|
||||||
win.ContentBlocking.enableForCurrentPage();
|
win.ContentBlocking.enableForCurrentPage();
|
||||||
|
|
|
@ -79,6 +79,8 @@ skip-if = serviceworker_e10s
|
||||||
[browser_storageAccessPromiseResolveHandlerUserInteraction.js]
|
[browser_storageAccessPromiseResolveHandlerUserInteraction.js]
|
||||||
[browser_storageAccessRemovalNavigateSubframe.js]
|
[browser_storageAccessRemovalNavigateSubframe.js]
|
||||||
skip-if = serviceworker_e10s
|
skip-if = serviceworker_e10s
|
||||||
|
[browser_storageAccessRemovalNavigateTopframe.js]
|
||||||
|
skip-if = serviceworker_e10s
|
||||||
[browser_storageAccessSandboxed.js]
|
[browser_storageAccessSandboxed.js]
|
||||||
skip-if = serviceworker_e10s
|
skip-if = serviceworker_e10s
|
||||||
[browser_storageAccessWithHeuristics.js]
|
[browser_storageAccessWithHeuristics.js]
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* import-globals-from antitracking_head.js */
|
||||||
|
|
||||||
|
AntiTracking.runTest("Storage Access is removed when topframe navigates",
|
||||||
|
// blocking callback
|
||||||
|
async _ => {
|
||||||
|
/* import-globals-from storageAccessAPIHelpers.js */
|
||||||
|
await noStorageAccessInitially();
|
||||||
|
},
|
||||||
|
|
||||||
|
// non-blocking callback
|
||||||
|
async _ => {
|
||||||
|
/* import-globals-from storageAccessAPIHelpers.js */
|
||||||
|
if (allowListed) {
|
||||||
|
await hasStorageAccessInitially();
|
||||||
|
} else {
|
||||||
|
await noStorageAccessInitially();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* import-globals-from storageAccessAPIHelpers.js */
|
||||||
|
let [threw, rejected] = await callRequestStorageAccess();
|
||||||
|
ok(!threw, "requestStorageAccess should not throw");
|
||||||
|
ok(!rejected, "requestStorageAccess should be available");
|
||||||
|
},
|
||||||
|
// cleanup function
|
||||||
|
async _ => {
|
||||||
|
await new Promise(resolve => {
|
||||||
|
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
null, // extra prefs
|
||||||
|
false, // no window open test
|
||||||
|
false, // no user-interaction test
|
||||||
|
0, // no blocking notifications
|
||||||
|
false, // run in normal window
|
||||||
|
null, // no iframe sandbox
|
||||||
|
"navigate-topframe", // access removal type
|
||||||
|
// after-removal callback
|
||||||
|
async _ => {
|
||||||
|
/* import-globals-from storageAccessAPIHelpers.js */
|
||||||
|
await noStorageAccessInitially();
|
||||||
|
}
|
||||||
|
);
|
Загрузка…
Ссылка в новой задаче