зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1522181 - multiple external protocol URL blocker behind pref, r=smaug
This commit is contained in:
Родитель
e2b193a67c
Коммит
0ae3238ccd
|
@ -9640,29 +9640,32 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
|
|||
aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_FRAME,
|
||||
"DoURILoad thinks this is a frame and InternalLoad does not");
|
||||
|
||||
// Only allow URLs able to return data in iframes.
|
||||
bool doesNotReturnData = false;
|
||||
NS_URIChainHasFlags(aLoadState->URI(),
|
||||
nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
|
||||
&doesNotReturnData);
|
||||
if (doesNotReturnData) {
|
||||
bool popupBlocked = true;
|
||||
if (StaticPrefs::dom_block_external_protocol_in_iframes()) {
|
||||
// Only allow URLs able to return data in iframes.
|
||||
bool doesNotReturnData = false;
|
||||
NS_URIChainHasFlags(aLoadState->URI(),
|
||||
nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
|
||||
&doesNotReturnData);
|
||||
if (doesNotReturnData) {
|
||||
bool popupBlocked = true;
|
||||
|
||||
// Let's consider external protocols as popups and let's check if the page
|
||||
// is allowed to open them without abuse regardless of allowed events
|
||||
if (PopupBlocker::GetPopupControlState() <= PopupBlocker::openBlocked) {
|
||||
popupBlocked = !PopupBlocker::TryUsePopupOpeningToken();
|
||||
} else {
|
||||
nsCOMPtr<nsINode> loadingNode =
|
||||
mScriptGlobal->AsOuter()->GetFrameElementInternal();
|
||||
if (loadingNode) {
|
||||
popupBlocked = !PopupBlocker::CanShowPopupByPermission(
|
||||
loadingNode->NodePrincipal());
|
||||
// Let's consider external protocols as popups and let's check if the
|
||||
// page is allowed to open them without abuse regardless of allowed
|
||||
// events
|
||||
if (PopupBlocker::GetPopupControlState() <= PopupBlocker::openBlocked) {
|
||||
popupBlocked = !PopupBlocker::TryUsePopupOpeningToken();
|
||||
} else {
|
||||
nsCOMPtr<nsINode> loadingNode =
|
||||
mScriptGlobal->AsOuter()->GetFrameElementInternal();
|
||||
if (loadingNode) {
|
||||
popupBlocked = !PopupBlocker::CanShowPopupByPermission(
|
||||
loadingNode->NodePrincipal());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (popupBlocked) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
if (popupBlocked) {
|
||||
return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,30 +10,35 @@
|
|||
<div id='foo'><a href='#'>Click here to test this issue</a></div>
|
||||
<script>
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let foo = document.getElementById('foo');
|
||||
foo.addEventListener('click', _ => {
|
||||
is(ChromeUtils.getPopupControlState(), "openAllowed", "Click events allow popups");
|
||||
ok(!ChromeUtils.isPopupTokenUnused(), "Popup token has not been used yet");
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
let ifr = document.createElement('iframe');
|
||||
ifr.src = "foo+bar:all_good";
|
||||
document.body.appendChild(ifr);
|
||||
|
||||
function next() {
|
||||
let foo = document.getElementById('foo');
|
||||
foo.addEventListener('click', _ => {
|
||||
is(ChromeUtils.getPopupControlState(), "openAllowed", "Click events allow popups");
|
||||
ok(ChromeUtils.isPopupTokenUnused(), "Popup token has been used!");
|
||||
}
|
||||
ok(!ChromeUtils.isPopupTokenUnused(), "Popup token has not been used yet");
|
||||
|
||||
SimpleTest.finish();
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
let ifr = document.createElement('iframe');
|
||||
ifr.src = "foo+bar:all_good";
|
||||
document.body.appendChild(ifr);
|
||||
|
||||
}, {once: true});
|
||||
is(ChromeUtils.getPopupControlState(), "openAllowed", "Click events allow popups");
|
||||
ok(ChromeUtils.isPopupTokenUnused(), "Popup token has been used!");
|
||||
}
|
||||
|
||||
setTimeout(_ => {
|
||||
sendMouseEvent({type:'click'}, 'foo');
|
||||
}, 0);
|
||||
SimpleTest.finish();
|
||||
|
||||
}, {once: true});
|
||||
|
||||
setTimeout(_ => {
|
||||
sendMouseEvent({type:'click'}, 'foo');
|
||||
}, 0);
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({'set': [
|
||||
['dom.block_external_protocol_in_iframes', true],
|
||||
]}, next);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -456,6 +456,19 @@ VARCACHE_PREF(
|
|||
RelaxedAtomicBool, false
|
||||
)
|
||||
|
||||
// Block multiple external protocol URLs in iframes per single event.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
#define PREF_VALUE true
|
||||
#else
|
||||
#define PREF_VALUE false
|
||||
#endif
|
||||
VARCACHE_PREF(
|
||||
"dom.block_external_protocol_in_iframes",
|
||||
dom_block_external_protocol_in_iframes,
|
||||
bool, PREF_VALUE
|
||||
)
|
||||
#undef PREF_VALUE
|
||||
|
||||
// Block multiple window.open() per single event.
|
||||
VARCACHE_PREF(
|
||||
"dom.block_multiple_popups",
|
||||
|
|
Загрузка…
Ссылка в новой задаче