Bug 1868387 - Part 1: Make a pref, that enables origin security check for SetDocumentURI() method, r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D195554
This commit is contained in:
aiunusov 2023-12-13 15:14:35 +00:00
parent b64693e408
commit 41283b7581
3 changed files with 67 additions and 57 deletions

View File

@ -8752,34 +8752,36 @@ nsresult nsDocShell::HandleSameDocumentNavigation(
("Upgraded URI to %s", newURI->GetSpecOrDefault().get()));
}
// check if aLoadState->URI(), principalURI, mCurrentURI are same origin
// skip handling otherwise
nsCOMPtr<nsIPrincipal> origPrincipal = doc->NodePrincipal();
nsCOMPtr<nsIURI> principalURI = origPrincipal->GetURI();
if (origPrincipal->GetIsNullPrincipal()) {
nsCOMPtr<nsIPrincipal> precursor = origPrincipal->GetPrecursorPrincipal();
if (precursor) {
principalURI = precursor->GetURI();
if (StaticPrefs::dom_security_setdocumenturi()) {
// check if aLoadState->URI(), principalURI, mCurrentURI are same origin
// skip handling otherwise
nsCOMPtr<nsIPrincipal> origPrincipal = doc->NodePrincipal();
nsCOMPtr<nsIURI> principalURI = origPrincipal->GetURI();
if (origPrincipal->GetIsNullPrincipal()) {
nsCOMPtr<nsIPrincipal> precursor = origPrincipal->GetPrecursorPrincipal();
if (precursor) {
principalURI = precursor->GetURI();
}
}
}
auto isLoadableViaInternet = [](nsIURI* uri) {
return (uri && (net::SchemeIsHTTP(uri) || net::SchemeIsHTTPS(uri)));
};
auto isLoadableViaInternet = [](nsIURI* uri) {
return (uri && (net::SchemeIsHTTP(uri) || net::SchemeIsHTTPS(uri)));
};
if (isLoadableViaInternet(principalURI) &&
isLoadableViaInternet(mCurrentURI) && isLoadableViaInternet(newURI)) {
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
if (!NS_SUCCEEDED(
ssm->CheckSameOriginURI(newURI, principalURI, false, false)) ||
!NS_SUCCEEDED(
ssm->CheckSameOriginURI(mCurrentURI, principalURI, false, false))) {
MOZ_LOG(gSHLog, LogLevel::Debug,
("nsDocShell[%p]: possible violation of the same origin policy "
"during same document navigation",
this));
aSameDocument = false;
return NS_OK;
if (isLoadableViaInternet(principalURI) &&
isLoadableViaInternet(mCurrentURI) && isLoadableViaInternet(newURI)) {
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
if (!NS_SUCCEEDED(
ssm->CheckSameOriginURI(newURI, principalURI, false, false)) ||
!NS_SUCCEEDED(ssm->CheckSameOriginURI(mCurrentURI, principalURI,
false, false))) {
MOZ_LOG(gSHLog, LogLevel::Debug,
("nsDocShell[%p]: possible violation of the same origin policy "
"during same document navigation",
this));
aSameDocument = false;
return NS_OK;
}
}
}

View File

@ -384,40 +384,42 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvInternalLoad(
IPCResult WindowGlobalParent::RecvUpdateDocumentURI(nsIURI* aURI) {
// XXX(nika): Assert that the URI change was one which makes sense (either
// about:blank -> a real URI, or a legal push/popstate URI change):
nsAutoCString scheme;
if (NS_FAILED(aURI->GetScheme(scheme))) {
return IPC_FAIL(this, "Setting DocumentURI without scheme.");
}
nsCOMPtr<nsIIOService> ios = do_GetIOService();
if (!ios) {
return IPC_FAIL(this, "Cannot get IOService");
}
nsCOMPtr<nsIProtocolHandler> handler;
ios->GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
if (!handler) {
return IPC_FAIL(this, "Setting DocumentURI with unknown protocol.");
}
auto isLoadableViaInternet = [](nsIURI* uri) {
return (uri && (net::SchemeIsHTTP(uri) || net::SchemeIsHTTPS(uri)));
};
if (isLoadableViaInternet(aURI)) {
nsCOMPtr<nsIURI> principalURI = mDocumentPrincipal->GetURI();
if (mDocumentPrincipal->GetIsNullPrincipal()) {
nsCOMPtr<nsIPrincipal> precursor =
mDocumentPrincipal->GetPrecursorPrincipal();
if (precursor) {
principalURI = precursor->GetURI();
}
if (StaticPrefs::dom_security_setdocumenturi()) {
nsAutoCString scheme;
if (NS_FAILED(aURI->GetScheme(scheme))) {
return IPC_FAIL(this, "Setting DocumentURI without scheme.");
}
if (isLoadableViaInternet(principalURI) &&
!nsScriptSecurityManager::SecurityCompareURIs(principalURI, aURI)) {
return IPC_FAIL(this,
"Setting DocumentURI with a different Origin than "
"principal URI");
nsCOMPtr<nsIIOService> ios = do_GetIOService();
if (!ios) {
return IPC_FAIL(this, "Cannot get IOService");
}
nsCOMPtr<nsIProtocolHandler> handler;
ios->GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
if (!handler) {
return IPC_FAIL(this, "Setting DocumentURI with unknown protocol.");
}
auto isLoadableViaInternet = [](nsIURI* uri) {
return (uri && (net::SchemeIsHTTP(uri) || net::SchemeIsHTTPS(uri)));
};
if (isLoadableViaInternet(aURI)) {
nsCOMPtr<nsIURI> principalURI = mDocumentPrincipal->GetURI();
if (mDocumentPrincipal->GetIsNullPrincipal()) {
nsCOMPtr<nsIPrincipal> precursor =
mDocumentPrincipal->GetPrecursorPrincipal();
if (precursor) {
principalURI = precursor->GetURI();
}
}
if (isLoadableViaInternet(principalURI) &&
!nsScriptSecurityManager::SecurityCompareURIs(principalURI, aURI)) {
return IPC_FAIL(this,
"Setting DocumentURI with a different Origin than "
"principal URI");
}
}
}

View File

@ -3794,6 +3794,12 @@
value: 120000
mirror: always
# SetDocumentURI security option, enforces origin check
- name: dom.security.setdocumenturi
type: bool
value: true
mirror: always
# Whether or not selection events on text controls are enabled.
- name: dom.select_events.textcontrols.selectionchange.enabled
type: bool