Bug 1835907, part 1 - Add has storage access bit and triggering window id to the LoadInfo - r=smaug,necko-reviewers,kershaw,pbz

In the Storage Access API's latest draft, a few items were added to the user-agent state. Relevant here,
the source snapshot params gained two fields that are initialized from the sourceDocument during
snapshotting source params while navigating: "has storage access" and "environment id".

https://privacycg.github.io/storage-access/#ua-state

These are used to identify self-initiated navigations that come from documents that have obtained storage access.
Combined with a same-origin check, this determines if the destination document of the navigation should start
with storage access.

This is stricter than the current behavior, where if the permission is available, all documents start with storage access.
Instead, now a document will only have storage access if it requests it explicitly or if a same-origin document that has
storage access navigates itself to that document. This is seen as a security win.

Security discussion of this change was here: https://github.com/privacycg/storage-access/issues/113
Artur at Google wrote up a great summary here: https://docs.google.com/document/d/1AsrETl-7XvnZNbG81Zy9BcZfKbqACQYBSrjM3VsIpjY/edit#

Differential Revision: https://phabricator.services.mozilla.com/D184821
This commit is contained in:
Benjamin VanderSloot
2023-08-14 18:02:46 +00:00
parent baf76b797c
commit b405b054f7
13 changed files with 182 additions and 5 deletions

View File

@@ -4014,6 +4014,13 @@ nsresult nsDocShell::LoadErrorPage(nsIURI* aErrorURI, nsIURI* aFailedURI,
loadState->SetTriggeringPrincipal(nsContentUtils::GetSystemPrincipal());
if (mBrowsingContext) {
loadState->SetTriggeringSandboxFlags(mBrowsingContext->GetSandboxFlags());
loadState->SetTriggeringWindowId(
mBrowsingContext->GetCurrentInnerWindowId());
nsPIDOMWindowInner* innerWin = mScriptGlobal->GetCurrentInnerWindow();
if (innerWin) {
loadState->SetTriggeringStorageAccess(
innerWin->HasStorageAccessPermissionGranted());
}
}
loadState->SetLoadType(LOAD_ERROR_PAGE);
loadState->SetFirstParty(true);
@@ -4200,6 +4207,8 @@ nsresult nsDocShell::ReloadDocument(nsDocShell* aDocShell, Document* aDocument,
nsIPrincipal* triggeringPrincipal = aDocument->NodePrincipal();
nsCOMPtr<nsIContentSecurityPolicy> csp = aDocument->GetCsp();
uint32_t triggeringSandboxFlags = aDocument->GetSandboxFlags();
uint64_t triggeringWindowId = aDocument->InnerWindowID();
bool triggeringStorageAccess = aDocument->HasStorageAccessPermissionGranted();
nsAutoString contentTypeHint;
aDocument->GetContentType(contentTypeHint);
@@ -4246,6 +4255,8 @@ nsresult nsDocShell::ReloadDocument(nsDocShell* aDocShell, Document* aDocument,
loadState->SetLoadReplace(loadReplace);
loadState->SetTriggeringPrincipal(triggeringPrincipal);
loadState->SetTriggeringSandboxFlags(triggeringSandboxFlags);
loadState->SetTriggeringWindowId(triggeringWindowId);
loadState->SetTriggeringStorageAccess(triggeringStorageAccess);
loadState->SetPrincipalToInherit(triggeringPrincipal);
loadState->SetCsp(csp);
loadState->SetInternalLoadFlags(flags);
@@ -5233,6 +5244,9 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
loadState->SetHasValidUserGestureActivation(
doc->HasValidTransientUserGestureActivation());
loadState->SetTriggeringSandboxFlags(doc->GetSandboxFlags());
loadState->SetTriggeringWindowId(doc->InnerWindowID());
loadState->SetTriggeringStorageAccess(
doc->HasStorageAccessPermissionGranted());
}
loadState->SetPrincipalIsExplicit(true);
@@ -8574,6 +8588,9 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) {
loadState->SetTriggeringPrincipal(aLoadState->TriggeringPrincipal());
loadState->SetTriggeringSandboxFlags(
aLoadState->TriggeringSandboxFlags());
loadState->SetTriggeringWindowId(aLoadState->TriggeringWindowId());
loadState->SetTriggeringStorageAccess(
aLoadState->TriggeringStorageAccess());
loadState->SetCsp(aLoadState->Csp());
loadState->SetInheritPrincipal(aLoadState->HasInternalLoadFlags(
INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL));
@@ -10511,9 +10528,16 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
}
}
if (mLoadType != LOAD_ERROR_PAGE && context && context->IsInProcess() &&
context->HasValidTransientUserGestureActivation()) {
if (mLoadType != LOAD_ERROR_PAGE && context && context->IsInProcess()) {
aLoadState->SetHasValidUserGestureActivation(true);
aLoadState->SetTriggeringWindowId(context->Id());
if (!aLoadState->TriggeringStorageAccess()) {
Document* contextDoc = context->GetExtantDoc();
if (contextDoc) {
aLoadState->SetTriggeringStorageAccess(
contextDoc->HasStorageAccessPermissionGranted());
}
}
}
// in case this docshell load was triggered by a valid transient user gesture,
@@ -10523,6 +10547,9 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
aLoadState->HasLoadFlags(LOAD_FLAGS_FROM_EXTERNAL)) {
loadInfo->SetHasValidUserGestureActivation(true);
}
loadInfo->SetTriggeringWindowId(aLoadState->TriggeringWindowId());
loadInfo->SetTriggeringStorageAccess(aLoadState->TriggeringStorageAccess());
loadInfo->SetTriggeringSandboxFlags(aLoadState->TriggeringSandboxFlags());
loadInfo->SetIsMetaRefresh(aLoadState->IsMetaRefresh());
@@ -13040,8 +13067,13 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent,
}
}
uint32_t triggeringSandboxFlags = 0;
uint64_t triggeringWindowId = 0;
bool triggeringStorageAccess = false;
if (mBrowsingContext) {
triggeringSandboxFlags = aContent->OwnerDoc()->GetSandboxFlags();
triggeringWindowId = aContent->OwnerDoc()->InnerWindowID();
triggeringStorageAccess =
aContent->OwnerDoc()->HasStorageAccessPermissionGranted();
}
uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
@@ -13149,6 +13181,8 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent,
RefPtr<WindowContext> context = mBrowsingContext->GetCurrentWindowContext();
aLoadState->SetTriggeringSandboxFlags(triggeringSandboxFlags);
aLoadState->SetTriggeringWindowId(triggeringWindowId);
aLoadState->SetTriggeringStorageAccess(triggeringStorageAccess);
aLoadState->SetReferrerInfo(referrerInfo);
aLoadState->SetInternalLoadFlags(flags);
aLoadState->SetTypeHint(NS_ConvertUTF16toUTF8(typeHint));