forked from mozilla/gecko-dev
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 1816287 - Always exit fullscreen when triggering on external prot…
…ocol r=edgar It's a security risk such that the maximized external program can obscure the fullscreen notification and the malicious site can use this trick to load a spoofed page in the background without user notices it. This patch minimized the risk by always exit the fullscreen mode when an external protocol is triggered. Differential Revision: https://phabricator.services.mozilla.com/D177771
- Loading branch information
Showing
12 changed files
with
196 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 160 additions & 0 deletions
160
dom/base/test/fullscreen/browser_fullscreen_exit_on_external_protocol.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
/* Any copyright is dedicated to the Public Domain. | ||
http://creativecommons.org/publicdomain/zero/1.0/ */ | ||
"use strict"; | ||
|
||
SimpleTest.requestCompleteLog(); | ||
|
||
requestLongerTimeout(2); | ||
|
||
// Import helpers | ||
Services.scriptloader.loadSubScript( | ||
"chrome://mochitests/content/browser/dom/base/test/fullscreen/fullscreen_helpers.js", | ||
this | ||
); | ||
|
||
add_setup(async function() { | ||
await pushPrefs( | ||
["full-screen-api.transition-duration.enter", "0 0"], | ||
["full-screen-api.transition-duration.leave", "0 0"], | ||
["full-screen-api.allow-trusted-requests-only", false] | ||
); | ||
}); | ||
|
||
const { HandlerServiceTestUtils } = ChromeUtils.importESModule( | ||
"resource://testing-common/HandlerServiceTestUtils.sys.mjs" | ||
); | ||
|
||
const gHandlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].getService( | ||
Ci.nsIHandlerService | ||
); | ||
|
||
const CONTENT = `data:text/html, | ||
<!DOCTYPE html> | ||
<html> | ||
<body> | ||
<button> | ||
<a href="mailto:[email protected]"></a> | ||
</button> | ||
</body> | ||
</html> | ||
`; | ||
|
||
// This test tends to trigger a race in the fullscreen time telemetry, | ||
// where the fullscreen enter and fullscreen exit events (which use the | ||
// same histogram ID) overlap. That causes TelemetryStopwatch to log an | ||
// error. | ||
SimpleTest.ignoreAllUncaughtExceptions(true); | ||
|
||
function setupMailHandler() { | ||
let mailHandlerInfo = HandlerServiceTestUtils.getHandlerInfo("mailto"); | ||
let gOldMailHandlers = []; | ||
|
||
// Remove extant web handlers because they have icons that | ||
// we fetch from the web, which isn't allowed in tests. | ||
let handlers = mailHandlerInfo.possibleApplicationHandlers; | ||
for (let i = handlers.Count() - 1; i >= 0; i--) { | ||
try { | ||
let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp); | ||
gOldMailHandlers.push(handler); | ||
// If we get here, this is a web handler app. Remove it: | ||
handlers.removeElementAt(i); | ||
} catch (ex) {} | ||
} | ||
|
||
let previousHandling = mailHandlerInfo.alwaysAskBeforeHandling; | ||
mailHandlerInfo.alwaysAskBeforeHandling = true; | ||
|
||
// Create a dummy web mail handler so we always know the mailto: protocol. | ||
// Without this, the test fails on VMs without a default mailto: handler, | ||
// because no dialog is ever shown, as we ignore subframe navigations to | ||
// protocols that cannot be handled. | ||
let dummy = Cc["@mozilla.org/uriloader/web-handler-app;1"].createInstance( | ||
Ci.nsIWebHandlerApp | ||
); | ||
dummy.name = "Handler 1"; | ||
dummy.uriTemplate = "https://example.com/first/%s"; | ||
mailHandlerInfo.possibleApplicationHandlers.appendElement(dummy); | ||
|
||
gHandlerSvc.store(mailHandlerInfo); | ||
registerCleanupFunction(() => { | ||
// Re-add the original protocol handlers: | ||
let mailHandlers = mailHandlerInfo.possibleApplicationHandlers; | ||
for (let i = handlers.Count() - 1; i >= 0; i--) { | ||
try { | ||
// See if this is a web handler. If it is, it'll throw, otherwise, | ||
// we will remove it. | ||
mailHandlers.queryElementAt(i, Ci.nsIWebHandlerApp); | ||
mailHandlers.removeElementAt(i); | ||
} catch (ex) {} | ||
} | ||
for (let h of gOldMailHandlers) { | ||
mailHandlers.appendElement(h); | ||
} | ||
mailHandlerInfo.alwaysAskBeforeHandling = previousHandling; | ||
gHandlerSvc.store(mailHandlerInfo); | ||
}); | ||
} | ||
|
||
add_task(setupMailHandler); | ||
|
||
add_task(async function OpenExternalProtocolOnPendingFullscreen() { | ||
for (const useClick of [true, false]) { | ||
await BrowserTestUtils.withNewTab(CONTENT, async browser => { | ||
const leavelFullscreen = waitForFullscreenState(document, false, true); | ||
await SpecialPowers.spawn(browser, [useClick], async function( | ||
shouldClick | ||
) { | ||
const button = content.document.querySelector("button"); | ||
|
||
const clickDone = new Promise(r => { | ||
button.addEventListener("click", function() { | ||
content.document.documentElement.requestFullscreen(); | ||
// When anchor.click() is called, the fullscreen request | ||
// is probably still pending. | ||
if (shouldClick) { | ||
content.document.querySelector("a").click(); | ||
} else { | ||
content.document.location = "mailto:[email protected]"; | ||
} | ||
r(); | ||
}); | ||
}); | ||
button.click(); | ||
await clickDone; | ||
}); | ||
|
||
await leavelFullscreen; | ||
ok(true, "Fullscreen should be exited"); | ||
}); | ||
} | ||
}); | ||
|
||
add_task(async function OpenExternalProtocolOnFullscreen() { | ||
for (const useClick of [true, false]) { | ||
await BrowserTestUtils.withNewTab(CONTENT, async browser => { | ||
const leavelFullscreen = waitForFullscreenState(document, false, true); | ||
await SpecialPowers.spawn(browser, [useClick], async function( | ||
shouldClick | ||
) { | ||
let button = content.document.querySelector("button"); | ||
button.addEventListener("click", function() { | ||
content.document.documentElement.requestFullscreen(); | ||
}); | ||
button.click(); | ||
|
||
await new Promise(r => { | ||
content.document.addEventListener("fullscreenchange", r); | ||
}); | ||
|
||
if (shouldClick) { | ||
content.document.querySelector("a").click(); | ||
} else { | ||
content.document.location = "mailto:[email protected]"; | ||
} | ||
}); | ||
|
||
await leavelFullscreen; | ||
ok(true, "Fullscreen should be exited"); | ||
}); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters