Bug 545812 - Only allow request and cancel full-screen api to work from a trusted event handler. r=smaug

This commit is contained in:
Chris Pearce 2011-09-05 08:40:18 +12:00
Родитель 02f249c072
Коммит 24027175fc
7 изменённых файлов: 78 добавлений и 9 удалений

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

@ -1705,6 +1705,14 @@ public:
*/
static PRBool IsFullScreenApiEnabled();
/**
* Returns PR_TRUE if requests for full-screen are allowed in the current
* context. Requests are only allowed if the user initiated them (like with
* a mouse-click or key press), unless this check has been disabled by
* setting the pref "full-screen-api.allow-trusted-requests-only" to false.
*/
static PRBool IsRequestFullScreenAllowed();
static void GetShiftText(nsAString& text);
static void GetControlText(nsAString& text);
static void GetMetaText(nsAString& text);
@ -1870,6 +1878,7 @@ private:
static PRBool sIsHandlingKeyBoardEvent;
static PRBool sAllowXULXBL_for_file;
static PRBool sIsFullScreenApiEnabled;
static PRBool sTrustedFullScreenOnly;
static nsHtml5Parser* sHTMLFragmentParser;
static nsIParser* sXMLFragmentParser;

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

@ -176,6 +176,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsIPluginHost.h"
#include "nsICategoryManager.h"
#include "nsIViewManager.h"
#include "nsEventStateManager.h"
#ifdef IBMBIDI
#include "nsIBidiKeyboard.h"
@ -262,6 +263,7 @@ nsString* nsContentUtils::sModifierSeparator = nsnull;
PRBool nsContentUtils::sInitialized = PR_FALSE;
PRBool nsContentUtils::sIsFullScreenApiEnabled = PR_FALSE;
PRBool nsContentUtils::sTrustedFullScreenOnly = PR_TRUE;
nsHtml5Parser* nsContentUtils::sHTMLFragmentParser = nsnull;
nsIParser* nsContentUtils::sXMLFragmentParser = nsnull;
@ -388,6 +390,9 @@ nsContentUtils::Init()
Preferences::AddBoolVarCache(&sIsFullScreenApiEnabled,
"full-screen-api.enabled");
Preferences::AddBoolVarCache(&sTrustedFullScreenOnly,
"full-screen-api.allow-trusted-requests-only");
sInitialized = PR_TRUE;
return NS_OK;
@ -5706,3 +5711,8 @@ nsContentUtils::IsFullScreenApiEnabled()
{
return sIsFullScreenApiEnabled;
}
PRBool nsContentUtils::IsRequestFullScreenAllowed()
{
return !sTrustedFullScreenOnly || nsEventStateManager::IsHandlingUserInput();
}

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

@ -8574,6 +8574,7 @@ NS_IMETHODIMP
nsDocument::MozCancelFullScreen()
{
if (!nsContentUtils::IsFullScreenApiEnabled() ||
!nsContentUtils::IsRequestFullScreenAllowed() ||
!IsFullScreenDoc() ||
!GetWindow()) {
return NS_OK;

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

@ -3381,7 +3381,13 @@ nsGenericHTMLElement::Focus()
nsresult nsGenericHTMLElement::MozRequestFullScreen()
{
if (!nsContentUtils::IsFullScreenApiEnabled()) {
// Only grant full-screen requests if this is called from inside a trusted
// event handler (i.e. inside an event handler for a user initiated event).
// This stops the full-screen from being abused similar to the popups of old,
// and it also makes it harder for bad guys' script to go full-screen and
// spoof the browser chrome/window and phish logins etc.
if (!nsContentUtils::IsFullScreenApiEnabled() ||
!nsContentUtils::IsRequestFullScreenAllowed()) {
return NS_OK;
}

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

@ -8,6 +8,7 @@ Test DOM full-screen API.
-->
<head>
<title>Test for Bug 545812</title>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<style>
body:-moz-full-screen, div:-moz-full-screen {
background-color: red;
@ -39,9 +40,18 @@ var iframeContents = "data:text/html;charset=utf-8,<html>%0D%0A <body onload%3D
var iframe = null;
var outOfDocElement = null;
var inDocElement = null;
var button = null;
var fullScreenChangeCount = 0;
function sendMouseClick(element) {
synthesizeMouseAtCenter(element, {});
}
function setRequireTrustedContext(value) {
opener.SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", value);
}
function fullScreenChange(event) {
switch (fullScreenChangeCount) {
case 0: {
@ -110,7 +120,27 @@ function fullScreenChange(event) {
}
case 5: {
ok(!document.mozFullScreen, "Should be back in non-full-screen mode (third time)");
setRequireTrustedContext(true);
document.body.mozRequestFullScreen();
ok(!document.mozFullScreen, "Should still be in normal mode, because calling context isn't trusted.");
button = document.createElement("button");
button.onclick = function(){document.body.mozRequestFullScreen();}
document.body.appendChild(button);
sendMouseClick(button);
break;
}
case 6: {
ok(document.mozFullScreen, "Moved to full-screen after mouse click");
document.mozCancelFullScreen();
ok(document.mozFullScreen, "Should still be in full-screen mode, because calling context isn't trusted.");
setRequireTrustedContext(false);
document.mozCancelFullScreen();
ok(!document.mozFullScreen, "Should have left full-screen mode.");
break;
}
case 7: {
ok(!document.mozFullScreen, "Should have left full-screen mode (last time).");
// Set timeout for calling finish(), so that any pending "mozfullscreenchange" events
// would have a chance to fire.
setTimeout(function(){opener.finish();}, 0);

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

@ -28,17 +28,29 @@ var requestFullScreenContents = "data:text/html;charset=utf-8,<html>%0D%0A <bod
function run() {
document.addEventListener("mozfullscreenchange",
function(){ok(false, "Should never receive a mozfullscreenchange event in the main window.");},
false);
// Ensure the full-screen api is enabled, and will be disabled on test exit.
var prevValue = SpecialPowers.getBoolPref("full-screen-api.enabled");
var prevEnabled = SpecialPowers.getBoolPref("full-screen-api.enabled");
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
window.addEventListener("unload", function() {
SpecialPowers.setBoolPref("full-screen-api.enabled", prevValue);
}, false);
var prevTrusted = SpecialPowers.getBoolPref("full-screen-api.allow-trusted-requests-only");
document.addEventListener("mozfullscreenchange",
function(){ok(false, "Should never receive a fullscreenchange event in the main window.");},
false);
// Request full-screen from a non trusted context (this script isn't a user
// generated event!). We should not receive a "mozfullscreenchange" event.
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", true);
document.body.mozRequestFullScreen();
// Disable the requirement for trusted contexts only, so the tests are easier
// to write.
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
window.addEventListener("unload", function() {
SpecialPowers.setBoolPref("full-screen-api.enabled", prevEnabled);
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", prevTrusted);
}, false);
// Load an iframe whose contents requests full-screen. This request should
// fail, and we should never receive a "mozfullscreenchange" event, because the

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

@ -3349,6 +3349,7 @@ pref("alerts.disableSlidingEffect", false);
// DOM full-screen API.
pref("full-screen-api.enabled", false);
pref("full-screen-api.allow-trusted-requests-only", true);
//3D Transforms
pref("layout.3d-transforms.enabled", false);