Bug 285438 Drag and drop gestures can be hijacked to load priviliged xul - xpfe/toolkit trunk patch v2.0
p=jst/me r=neil.parkwaycc.co.uk sr=bzbarsky a=benjamin
This commit is contained in:
Родитель
e4c37dd5c0
Коммит
cb9cb1cecd
|
@ -1849,7 +1849,7 @@
|
|||
<method name="dragDropSecurityCheck">
|
||||
<parameter name="aEvent"/>
|
||||
<parameter name="aDragSession"/>
|
||||
<parameter name="aUrl"/>
|
||||
<parameter name="aUri"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
// Do a security check for drag n' drop. Make sure the
|
||||
|
@ -1857,22 +1857,44 @@
|
|||
var sourceDoc = aDragSession.sourceDocument;
|
||||
|
||||
if (sourceDoc) {
|
||||
var sourceURI = sourceDoc.documentURI;
|
||||
// Strip leading and trailing whitespace, then try to
|
||||
// create a URI from the dropped string. If that
|
||||
// succeeds, we're dropping a URI and we need to do a
|
||||
// security check to make sure the source document can
|
||||
// load the dropped URI. We don't so much care about
|
||||
// creating the real URI here (i.e. encoding differences
|
||||
// etc don't matter), we just want to know if aUri
|
||||
// really is a URI.
|
||||
|
||||
const nsIScriptSecurityManager =
|
||||
Components.interfaces.nsIScriptSecurityManager;
|
||||
var secMan =
|
||||
Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(nsIScriptSecurityManager);
|
||||
var uriStr = aUri.replace(/^\s*|\s*$/g, '');
|
||||
var uri = null;
|
||||
|
||||
try {
|
||||
secMan.checkLoadURIStr(sourceURI, aUrl,
|
||||
nsIScriptSecurityManager.STANDARD);
|
||||
uri = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService)
|
||||
.newURI(uriStr, null, null);
|
||||
} catch (e) {
|
||||
// Stop event propagation right here.
|
||||
aEvent.stopPropagation();
|
||||
}
|
||||
|
||||
throw "Drop of " + aUrl + " denied.";
|
||||
if (uri) {
|
||||
// aUri is a URI, do the security check.
|
||||
var sourceURI = sourceDoc.documentURI;
|
||||
|
||||
const nsIScriptSecurityManager =
|
||||
Components.interfaces.nsIScriptSecurityManager;
|
||||
var secMan =
|
||||
Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(nsIScriptSecurityManager);
|
||||
|
||||
try {
|
||||
secMan.checkLoadURIStr(sourceURI, uriStr,
|
||||
nsIScriptSecurityManager.STANDARD);
|
||||
} catch (e) {
|
||||
// Stop event propagation right here.
|
||||
aEvent.stopPropagation();
|
||||
|
||||
throw "Drop of " + aUri + " denied.";
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
|
|
|
@ -1,212 +0,0 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* - Kevin Puetz (puetzk@iastate.edu)
|
||||
* - Ben Goodger <ben@netscape.com>
|
||||
* - Blake Ross <blaker@netscape.com>
|
||||
* - Pierre Chanial <pierrechanial@netscape.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
function _RDF(aType)
|
||||
{
|
||||
return "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + aType;
|
||||
}
|
||||
function NC_RDF(aType)
|
||||
{
|
||||
return "http://home.netscape.com/NC-rdf#" + aType;
|
||||
}
|
||||
|
||||
var RDFUtils = {
|
||||
getResource: function(aString)
|
||||
{
|
||||
return this.rdf.GetResource(aString, true);
|
||||
},
|
||||
|
||||
getTarget: function(aDS, aSourceID, aPropertyID)
|
||||
{
|
||||
var source = this.getResource(aSourceID);
|
||||
var property = this.getResource(aPropertyID);
|
||||
return aDS.GetTarget(source, property, true);
|
||||
},
|
||||
|
||||
getValueFromResource: function(aResource)
|
||||
{
|
||||
aResource = aResource.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
return aResource ? aResource.Value : null;
|
||||
},
|
||||
_rdf: null,
|
||||
get rdf() {
|
||||
if (!this._rdf) {
|
||||
this._rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"]
|
||||
.getService(Components.interfaces.nsIRDFService);
|
||||
}
|
||||
return this._rdf;
|
||||
}
|
||||
}
|
||||
|
||||
var proxyIconDNDObserver = {
|
||||
onDragStart: function (aEvent, aXferData, aDragAction)
|
||||
{
|
||||
var urlBar = document.getElementById("urlbar");
|
||||
|
||||
// XXX - do we want to allow the user to set a blank page to their homepage?
|
||||
// if so then we want to modify this a little to set about:blank as
|
||||
// the homepage in the event of an empty urlbar.
|
||||
if (!urlBar.value) return;
|
||||
|
||||
var urlString = urlBar.value + "\n" + window.content.document.title;
|
||||
var htmlString = "<a href=\"" + urlBar.value + "\">" + urlBar.value + "</a>";
|
||||
|
||||
aXferData.data = new TransferData();
|
||||
aXferData.data.addDataForFlavour("text/x-moz-url", urlString);
|
||||
aXferData.data.addDataForFlavour("text/unicode", urlBar.value);
|
||||
aXferData.data.addDataForFlavour("text/html", htmlString);
|
||||
}
|
||||
}
|
||||
|
||||
var homeButtonObserver = {
|
||||
onDragStart: function (aEvent, aXferData, aDragAction)
|
||||
{
|
||||
var homepage = nsPreferences.getLocalizedUnicharPref("browser.startup.homepage", "about:blank");
|
||||
|
||||
if (homepage)
|
||||
{
|
||||
// XXX find a readable title string for homepage, perhaps do a history lookup.
|
||||
var htmlString = "<a href=\"" + homepage + "\">" + homepage + "</a>";
|
||||
aXferData.data = new TransferData();
|
||||
aXferData.data.addDataForFlavour("text/x-moz-url", homepage + "\n" + homepage);
|
||||
aXferData.data.addDataForFlavour("text/html", htmlString);
|
||||
aXferData.data.addDataForFlavour("text/unicode", homepage);
|
||||
}
|
||||
},
|
||||
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
{
|
||||
var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
|
||||
setTimeout(openHomeDialog, 0, url);
|
||||
},
|
||||
|
||||
onDragOver: function (aEvent, aFlavour, aDragSession)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = gNavigatorBundle.getString("droponhomebutton");
|
||||
aDragSession.dragAction = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
||||
},
|
||||
|
||||
onDragExit: function (aEvent, aDragSession)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = "";
|
||||
},
|
||||
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("text/unicode");
|
||||
return flavourSet;
|
||||
}
|
||||
}
|
||||
|
||||
function openHomeDialog(aURL)
|
||||
{
|
||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
|
||||
var promptTitle = gNavigatorBundle.getString("droponhometitle");
|
||||
var promptMsg = gNavigatorBundle.getString("droponhomemsg");
|
||||
var okButton = gNavigatorBundle.getString("droponhomeokbutton");
|
||||
var pressedVal = promptService.confirmEx(window, promptTitle, promptMsg,
|
||||
(promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0) +
|
||||
(promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
|
||||
okButton, null, null, null, {value:0});
|
||||
|
||||
if (pressedVal == 0) {
|
||||
nsPreferences.setUnicharPref("browser.startup.homepage", aURL);
|
||||
}
|
||||
}
|
||||
|
||||
var goButtonObserver = {
|
||||
onDragOver: function(aEvent, aFlavour, aDragSession)
|
||||
{
|
||||
aEvent.target.setAttribute("dragover", "true");
|
||||
return true;
|
||||
},
|
||||
onDragExit: function (aEvent, aDragSession)
|
||||
{
|
||||
aEvent.target.removeAttribute("dragover");
|
||||
},
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
{
|
||||
var xferData = aXferData.data.split("\n");
|
||||
var uri = xferData[0] ? xferData[0] : xferData[1];
|
||||
if (uri)
|
||||
loadURI(uri);
|
||||
},
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("text/unicode");
|
||||
return flavourSet;
|
||||
}
|
||||
}
|
||||
|
||||
var searchButtonObserver = {
|
||||
onDragOver: function(aEvent, aFlavour, aDragSession)
|
||||
{
|
||||
aEvent.target.setAttribute("dragover", "true");
|
||||
return true;
|
||||
},
|
||||
onDragExit: function (aEvent, aDragSession)
|
||||
{
|
||||
aEvent.target.removeAttribute("dragover");
|
||||
},
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
{
|
||||
var xferData = aXferData.data.split("\n");
|
||||
var uri = xferData[1] ? xferData[1] : xferData[0];
|
||||
if (uri)
|
||||
OpenSearch('internet', uri);
|
||||
},
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("text/unicode");
|
||||
return flavourSet;
|
||||
}
|
||||
}
|
|
@ -62,6 +62,9 @@ var contentAreaDNDObserver = {
|
|||
|
||||
switch (document.firstChild.getAttribute('windowtype')) {
|
||||
case "navigator:browser":
|
||||
// Perform a security check before loading the URI
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url);
|
||||
|
||||
loadURI(getShortcutOrURI(url));
|
||||
break;
|
||||
case "navigator:view-source":
|
||||
|
|
|
@ -1168,6 +1168,9 @@
|
|||
/^\s*(javascript|data):/.test(url))
|
||||
return;
|
||||
|
||||
// Perform a security check before loading the URI
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url);
|
||||
|
||||
var bgLoad = this.mPrefs.getBoolPref("browser.tabs.loadInBackground");
|
||||
|
||||
var tab = null;
|
||||
|
|
|
@ -325,6 +325,63 @@ var nsDragAndDrop = {
|
|||
if ("canDrop" in aDragDropObserver)
|
||||
this.mDragSession.canDrop &= aDragDropObserver.canDrop(aEvent, this.mDragSession);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Do a security check for drag n' drop. Make sure the source document
|
||||
* can load the dragged link.
|
||||
*
|
||||
* @param DOMEvent aEvent
|
||||
* the DOM event fired by leaving the element
|
||||
* @param Object aDragDropObserver
|
||||
* javascript object of format described above that specifies
|
||||
* the way in which the element responds to drag events.
|
||||
* @param String aUri
|
||||
* the uri being dragged
|
||||
**/
|
||||
dragDropSecurityCheck: function (aEvent, aDragSession, aUri)
|
||||
{
|
||||
var sourceDoc = aDragSession.sourceDocument;
|
||||
|
||||
if (sourceDoc) {
|
||||
// Strip leading and trailing whitespace, then try to create a
|
||||
// URI from the dropped string. If that succeeds, we're
|
||||
// dropping a URI and we need to do a security check to make
|
||||
// sure the source document can load the dropped URI. We don't
|
||||
// so much care about creating the real URI here
|
||||
// (i.e. encoding differences etc don't matter), we just want
|
||||
// to know if aUri really is a URI.
|
||||
|
||||
var uriStr = aUri.replace(/^\s*|\s*$/g, '');
|
||||
var uri = null;
|
||||
|
||||
try {
|
||||
uri = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService)
|
||||
.newURI(uriStr, null, null);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (uri) {
|
||||
// aUri is a URI, do the security check.
|
||||
var sourceURI = sourceDoc.documentURI;
|
||||
|
||||
const nsIScriptSecurityManager =
|
||||
Components.interfaces.nsIScriptSecurityManager;
|
||||
var secMan =
|
||||
Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(nsIScriptSecurityManager);
|
||||
|
||||
try {
|
||||
secMan.checkLoadURIStr(sourceURI, uriStr,
|
||||
nsIScriptSecurityManager.STANDARD);
|
||||
} catch (e) {
|
||||
// Stop event propagation right here.
|
||||
aEvent.stopPropagation();
|
||||
|
||||
throw "Drop of " + aUri + " denied.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче