Bug 1687805 - Part 2: Don't use OpenNoNavigate if noopener is force-enabled, r=kmag

Differential Revision: https://phabricator.services.mozilla.com/D103360
This commit is contained in:
Nika Layzell 2021-01-29 22:15:44 +00:00
Родитель 51b5d48b77
Коммит 8c7b06dc23
3 изменённых файлов: 41 добавлений и 16 удалений

Просмотреть файл

@ -8437,6 +8437,19 @@ nsContentPolicyType nsDocShell::DetermineContentType() {
: nsIContentPolicy::TYPE_INTERNAL_FRAME;
}
bool nsDocShell::NoopenerForceEnabled() {
// If current's top-level browsing context's active document's
// cross-origin-opener-policy is "same-origin" or "same-origin + COEP" then
// if currentDoc's origin is not same origin with currentDoc's top-level
// origin, noopener is force enabled, and name is cleared to "_blank".
auto topPolicy = mBrowsingContext->Top()->GetOpenerPolicy();
return (topPolicy == nsILoadInfo::OPENER_POLICY_SAME_ORIGIN ||
topPolicy ==
nsILoadInfo::
OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP) &&
!mBrowsingContext->SameOriginWithTop();
}
nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) {
MOZ_ASSERT(aLoadState, "need a load state!");
MOZ_ASSERT(!aLoadState->Target().IsEmpty(), "should have a target here!");
@ -8550,17 +8563,18 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) {
// If we are a noopener load, we just hand the whole thing over to our
// window.
if (aLoadState->HasInternalLoadFlags(INTERNAL_LOAD_FLAGS_NO_OPENER)) {
if (aLoadState->HasInternalLoadFlags(INTERNAL_LOAD_FLAGS_NO_OPENER) ||
NoopenerForceEnabled()) {
// Various asserts that we know to hold because NO_OPENER loads can only
// happen for links.
MOZ_ASSERT(!aLoadState->LoadReplace());
MOZ_ASSERT(aLoadState->PrincipalToInherit() ==
aLoadState->TriggeringPrincipal());
MOZ_ASSERT(aLoadState->InternalLoadFlags() ==
INTERNAL_LOAD_FLAGS_NO_OPENER ||
aLoadState->InternalLoadFlags() ==
(INTERNAL_LOAD_FLAGS_NO_OPENER |
INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER));
MOZ_ASSERT(!(aLoadState->InternalLoadFlags() &
~(INTERNAL_LOAD_FLAGS_NO_OPENER |
INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER)),
"Only INTERNAL_LOAD_FLAGS_NO_OPENER and "
"INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER can be set");
MOZ_ASSERT(!aLoadState->PostDataStream());
MOZ_ASSERT(!aLoadState->HeadersStream());
// If OnLinkClickSync was invoked inside the onload handler, the load

Просмотреть файл

@ -1059,6 +1059,12 @@ class nsDocShell final : public nsDocLoader,
void ActivenessMaybeChanged();
/**
* Returns true if `noopener` will be force-enabled by any attempt to create
* a popup window, even if rel="opener" is requested.
*/
bool NoopenerForceEnabled();
private: // data members
nsString mTitle;
nsCString mOriginalUriString;

Просмотреть файл

@ -6934,17 +6934,22 @@ nsresult nsGlobalWindowOuter::OpenInternal(
nsAutoCString options;
features.Stringify(options);
// If current's top-level browsing context's active document's
// cross-origin-opener-policy is "same-origin" or "same-origin + COEP" then
// if currentDoc's origin is not same origin with currentDoc's top-level
// origin, then set noopener to true and name to "_blank".
// If noopener is force-enabled for the current document, then set noopener to
// true, and clear the name to "_blank".
nsAutoString windowName(aName);
auto topPolicy = mBrowsingContext->Top()->GetOpenerPolicy();
if ((topPolicy == nsILoadInfo::OPENER_POLICY_SAME_ORIGIN ||
topPolicy ==
nsILoadInfo::
OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP) &&
!mBrowsingContext->SameOriginWithTop()) {
if (nsDocShell::Cast(GetDocShell())->NoopenerForceEnabled()) {
// FIXME: Eventually bypass force-enabling noopener if `aPrintKind !=
// PrintKind::None`, so that we can print pages with noopener force-enabled.
// This will require relaxing assertions elsewhere.
if (aPrintKind != PrintKind::None) {
NS_WARNING(
"printing frames with noopener force-enabled isn't supported yet");
return NS_ERROR_FAILURE;
}
MOZ_DIAGNOSTIC_ASSERT(aNavigate,
"cannot OpenNoNavigate if noopener is force-enabled");
forceNoOpener = true;
windowName = u"_blank"_ns;
}