diff options
author | Moonchild <mcwerewolf@gmail.com> | 2018-05-01 09:53:46 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-01 09:53:46 +0200 |
commit | ae45e61da06ba989fcbb856183d9578d4d4f51ed (patch) | |
tree | 5c7dea17ce684c1cce57011ef487370c22d0e677 /browser | |
parent | fefce8f7ccbc476cfc46e61b01eff069346d3c73 (diff) | |
parent | cc4036a9cd56d504667c07fe215e61b22ab0e1f4 (diff) | |
download | UXP-ae45e61da06ba989fcbb856183d9578d4d4f51ed.tar UXP-ae45e61da06ba989fcbb856183d9578d4d4f51ed.tar.gz UXP-ae45e61da06ba989fcbb856183d9578d4d4f51ed.tar.lz UXP-ae45e61da06ba989fcbb856183d9578d4d4f51ed.tar.xz UXP-ae45e61da06ba989fcbb856183d9578d4d4f51ed.zip |
Merge pull request #311 from janekptacijarabaci/security_blocking_data_2
Use asyncOpen2() for docshell loads
Diffstat (limited to 'browser')
-rwxr-xr-x | browser/base/content/browser.js | 83 | ||||
-rw-r--r-- | browser/base/content/content.js | 2 | ||||
-rw-r--r-- | browser/base/content/nsContextMenu.js | 5 | ||||
-rw-r--r-- | browser/base/content/tabbrowser.xml | 6 | ||||
-rw-r--r-- | browser/base/content/utilityOverlay.js | 22 | ||||
-rw-r--r-- | browser/components/feeds/FeedConverter.js | 2 | ||||
-rw-r--r-- | browser/components/sessionstore/ContentRestore.jsm | 5 | ||||
-rw-r--r-- | browser/components/sessionstore/SessionHistory.jsm | 5 | ||||
-rw-r--r-- | browser/components/sessionstore/SessionMigration.jsm | 14 | ||||
-rw-r--r-- | browser/components/sessionstore/SessionStore.jsm | 4 | ||||
-rw-r--r-- | browser/modules/ContentClick.jsm | 1 |
11 files changed, 84 insertions, 65 deletions
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 696a2871a..2380f5d21 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -71,6 +71,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing", ["gDNSService", "@mozilla.org/network/dns-service;1", "nsIDNSService"], ].forEach(([name, cc, ci]) => XPCOMUtils.defineLazyServiceGetter(this, name, cc, ci)); +XPCOMUtils.defineLazyServiceGetter(this, "gSerializationHelper", + "@mozilla.org/network/serialization-helper;1", + "nsISerializationHelper"); + XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function() { let tmp = {}; Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", tmp); @@ -807,6 +811,7 @@ function _loadURIWithFlags(browser, uri, params) { if (!uri) { uri = "about:blank"; } + let triggeringPrincipal = params.triggeringPrincipal || null; let flags = params.flags || 0; let referrer = params.referrerURI; let referrerPolicy = ('referrerPolicy' in params ? params.referrerPolicy : @@ -831,7 +836,7 @@ function _loadURIWithFlags(browser, uri, params) { browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy, - postData, null, null); + postData, null, null, triggeringPrincipal); } else { // Check if the current browser is allowed to unload. let {permitUnload, timedOut} = browser.permitUnload(); @@ -845,6 +850,9 @@ function _loadURIWithFlags(browser, uri, params) { let loadParams = { uri: uri, + triggeringPrincipal: triggeringPrincipal + ? gSerializationHelper.serializeToString(triggeringPrincipal) + : null, flags: flags, referrer: referrer ? referrer.spec : null, referrerPolicy: referrerPolicy, @@ -872,7 +880,7 @@ function _loadURIWithFlags(browser, uri, params) { } browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy, - postData, null, null); + postData, null, null, triggeringPrincipal); } else { throw e; } @@ -1164,6 +1172,7 @@ var gBrowserInit = { // [5]: referrerPolicy (int) // [6]: userContextId (int) // [7]: originPrincipal (nsIPrincipal) + // [8]: triggeringPrincipal (nsIPrincipal) else if (window.arguments.length >= 3) { let referrerURI = window.arguments[2]; if (typeof(referrerURI) == "string") { @@ -1181,7 +1190,7 @@ var gBrowserInit = { window.arguments[4] || false, referrerPolicy, userContextId, // pass the origin principal (if any) and force its use to create // an initial about:blank viewer if present: - window.arguments[7], !!window.arguments[7]); + window.arguments[7], !!window.arguments[7], window.arguments[8]); window.focus(); } // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3. @@ -2067,7 +2076,8 @@ function BrowserTryToCloseWindow() } function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy, - userContextId, originPrincipal, forceAboutBlankViewerInCurrent) { + userContextId, originPrincipal, forceAboutBlankViewerInCurrent, + triggeringPrincipal) { try { openLinkIn(uri, "current", { referrerURI: referrer, @@ -2076,6 +2086,7 @@ function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy, allowThirdPartyFixup: allowThirdPartyFixup, userContextId: userContextId, originPrincipal, + triggeringPrincipal, forceAboutBlankViewerInCurrent, }); } catch (e) {} @@ -2779,24 +2790,6 @@ var BrowserOnClick = { } }, - handleEvent: function (event) { - if (!event.isTrusted || // Don't trust synthetic events - event.button == 2) { - return; - } - - let originalTarget = event.originalTarget; - let ownerDoc = originalTarget.ownerDocument; - if (!ownerDoc) { - return; - } - - if (gMultiProcessBrowser && - ownerDoc.documentURI.toLowerCase() == "about:newtab") { - this.onE10sAboutNewTab(event, ownerDoc); - } - }, - receiveMessage: function (msg) { switch (msg.name) { case "Browser:CertExceptionError": @@ -2990,28 +2983,6 @@ var BrowserOnClick = { } }, - /** - * This functions prevents navigation from happening directly through the <a> - * link in about:newtab (which is loaded in the parent and therefore would load - * the next page also in the parent) and instructs the browser to open the url - * in the current tab which will make it update the remoteness of the tab. - */ - onE10sAboutNewTab: function(event, ownerDoc) { - let isTopFrame = (ownerDoc.defaultView.parent === ownerDoc.defaultView); - if (!isTopFrame) { - return; - } - - let anchorTarget = event.originalTarget.parentNode; - - if (anchorTarget instanceof HTMLAnchorElement && - anchorTarget.classList.contains("newtab-link")) { - event.preventDefault(); - let where = whereToOpenLink(event, false, false); - openLinkIn(anchorTarget.href, where, { charset: ownerDoc.characterSet, referrerURI: ownerDoc.documentURIObject }); - } - }, - ignoreWarningButton: function (reason) { // Allow users to override and continue through to the site, // but add a notify bar as a reminder, so that they don't lose @@ -4809,13 +4780,9 @@ var TabsProgressListener = { } } - // Attach a listener to watch for "click" events bubbling up from error - // pages and other similar pages (like about:newtab). This lets us fix bugs - // like 401575 which require error page UI to do privileged things, without - // letting error pages have any privilege themselves. - // We can't look for this during onLocationChange since at that point the - // document URI is not yet the about:-uri of the error page. - + // We used to listen for clicks in the browser here, but when that + // became unnecessary, removing the code below caused focus issues. + // This code should be removed. Tracked in bug 1337794. let isRemoteBrowser = aBrowser.isRemoteBrowser; // We check isRemoteBrowser here to avoid requesting the doc CPOW let doc = isRemoteBrowser ? null : aWebProgress.DOMWindow.document; @@ -4830,11 +4797,9 @@ var TabsProgressListener = { // STATE_STOP may be received twice for documents, thus store an // attribute to ensure handling it just once. doc.documentElement.setAttribute("hasBrowserHandlers", "true"); - aBrowser.addEventListener("click", BrowserOnClick, true); aBrowser.addEventListener("pagehide", function onPageHide(event) { if (event.target.defaultView.frameElement) return; - aBrowser.removeEventListener("click", BrowserOnClick, true); aBrowser.removeEventListener("pagehide", onPageHide, true); if (event.target.documentElement) event.target.documentElement.removeAttribute("hasBrowserHandlers"); @@ -4883,7 +4848,7 @@ nsBrowserAccess.prototype = { _openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate, aIsExternal, aForceNotRemote=false, aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID, - aOpener=null) { + aOpener = null, aTriggeringPrincipal = null) { let win, needToFocusWin; // try the current window. if we're in a popup, fall back on the most recent browser window @@ -4908,6 +4873,7 @@ nsBrowserAccess.prototype = { let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"); let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", { + triggeringPrincipal: aTriggeringPrincipal, referrerURI: aReferrer, referrerPolicy: aReferrerPolicy, userContextId: aUserContextId, @@ -4956,9 +4922,11 @@ nsBrowserAccess.prototype = { } let referrer = aOpener ? makeURI(aOpener.location.href) : null; + let triggeringPrincipal = null; let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT; if (aOpener && aOpener.document) { referrerPolicy = aOpener.document.referrerPolicy; + triggeringPrincipal = aOpener.document.nodePrincipal; } let isPrivate = aOpener ? PrivateBrowsingUtils.isContentWindowPrivate(aOpener) @@ -4992,7 +4960,7 @@ nsBrowserAccess.prototype = { let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy, isPrivate, isExternal, forceNotRemote, userContextId, - openerWindow); + openerWindow, triggeringPrincipal); if (browser) newWindow = browser.contentWindow; break; @@ -5003,6 +4971,7 @@ nsBrowserAccess.prototype = { Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL : Ci.nsIWebNavigation.LOAD_FLAGS_NONE; gBrowser.loadURIWithFlags(aURI.spec, { + triggeringPrincipal, flags: loadflags, referrerURI: referrer, referrerPolicy: referrerPolicy, @@ -5031,7 +5000,8 @@ nsBrowserAccess.prototype = { aParams.referrerPolicy, aParams.isPrivate, isExternal, false, - userContextId); + userContextId, null, + aParams.triggeringPrincipal); if (browser) return browser.QueryInterface(Ci.nsIFrameLoaderOwner); @@ -5584,6 +5554,7 @@ function handleLinkClick(event, href, linkNode) { referrerPolicy: referrerPolicy, noReferrer: BrowserUtils.linkHasNoReferrer(linkNode), originPrincipal: doc.nodePrincipal, + triggeringPrincipal: doc.nodePrincipal, }; // The new tab/window must use the same userContextId diff --git a/browser/base/content/content.js b/browser/base/content/content.js index 8d6f0745e..46e9b45d6 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -482,6 +482,7 @@ var ClickEventHandler = { ctrlKey: event.ctrlKey, metaKey: event.metaKey, altKey: event.altKey, href: null, title: null, bookmark: false, referrerPolicy: referrerPolicy, + triggeringPrincipal: principal, originAttributes: principal ? principal.originAttributes : {}, isContentWindowPrivate: PrivateBrowsingUtils.isContentWindowPrivate(ownerDoc.defaultView)}; @@ -521,6 +522,7 @@ var ClickEventHandler = { } catch (e) {} } json.originPrincipal = ownerDoc.nodePrincipal; + json.triggeringPrincipal = ownerDoc.nodePrincipal; sendAsyncMessage("Content:Click", json); return; diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js index ddf695202..955184f64 100644 --- a/browser/base/content/nsContextMenu.js +++ b/browser/base/content/nsContextMenu.js @@ -968,6 +968,7 @@ nsContextMenu.prototype = { _openLinkInParameters : function (extra) { let params = { charset: gContextMenuContentData.charSet, originPrincipal: this.principal, + triggeringPrincipal: this.principal, referrerURI: gContextMenuContentData.documentURIObject, referrerPolicy: gContextMenuContentData.referrerPolicy, noReferrer: this.linkHasNoReferrer }; @@ -1147,10 +1148,12 @@ nsContextMenu.prototype = { // Change current window to the URL of the image, video, or audio. viewMedia: function(e) { let referrerURI = gContextMenuContentData.documentURIObject; + let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); if (this.onCanvas) { this._canvasToBlobURL(this.target).then(function(blobURL) { openUILink(blobURL, e, { disallowInheritPrincipal: true, - referrerURI: referrerURI }); + referrerURI: referrerURI, + triggeringPrincipal: systemPrincipal}); }, Cu.reportError); } else { diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index b27846835..463e74a52 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1513,6 +1513,7 @@ <parameter name="aAllowThirdPartyFixup"/> <body> <![CDATA[ + var aTriggeringPrincipal; var aReferrerPolicy; var aFromExternal; var aRelatedToCurrent; @@ -1528,6 +1529,7 @@ typeof arguments[1] == "object" && !(arguments[1] instanceof Ci.nsIURI)) { let params = arguments[1]; + aTriggeringPrincipal = params.triggeringPrincipal aReferrerURI = params.referrerURI; aReferrerPolicy = params.referrerPolicy; aCharset = params.charset; @@ -1550,6 +1552,7 @@ Services.prefs.getBoolPref("browser.tabs.loadInBackground"); var owner = bgLoad ? null : this.selectedTab; var tab = this.addTab(aURI, { + triggeringPrincipal: aTriggeringPrincipal, referrerURI: aReferrerURI, referrerPolicy: aReferrerPolicy, charset: aCharset, @@ -2120,6 +2123,7 @@ "use strict"; const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + var aTriggeringPrincipal; var aReferrerPolicy; var aFromExternal; var aRelatedToCurrent; @@ -2136,6 +2140,7 @@ typeof arguments[1] == "object" && !(arguments[1] instanceof Ci.nsIURI)) { let params = arguments[1]; + aTriggeringPrincipal = params.triggeringPrincipal; aReferrerURI = params.referrerURI; aReferrerPolicy = params.referrerPolicy; aCharset = params.charset; @@ -2267,6 +2272,7 @@ try { b.loadURIWithFlags(aURI, { flags, + triggeringPrincipal: aTriggeringPrincipal, referrerURI: aNoReferrer ? null: aReferrerURI, referrerPolicy: aReferrerPolicy, charset: aCharset, diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js index 6ceaf773e..b041915a7 100644 --- a/browser/base/content/utilityOverlay.js +++ b/browser/base/content/utilityOverlay.js @@ -225,6 +225,7 @@ function openLinkIn(url, where, params) { var aUserContextId = params.userContextId; var aIndicateErrorPageLoad = params.indicateErrorPageLoad; var aPrincipal = params.originPrincipal; + var aTriggeringPrincipal = params.triggeringPrincipal; var aForceAboutBlankViewerInCurrent = params.forceAboutBlankViewerInCurrent; @@ -259,6 +260,24 @@ function openLinkIn(url, where, params) { return; } + // Teach the principal about the right OA to use, e.g. in case when + // opening a link in a new private window, or in a new container tab. + // Please note we do not have to do that for SystemPrincipals and we + // can not do it for NullPrincipals since NullPrincipals are only + // identical if they actually are the same object (See Bug: 1346759) + function useOAForPrincipal(principal) { + if (principal && principal.isCodebasePrincipal) { + let attrs = { + userContextId: aUserContextId, + privateBrowsingId: aIsPrivate || (w && PrivateBrowsingUtils.isWindowPrivate(w)), + }; + return Services.scriptSecurityManager.createCodebasePrincipal(principal.URI, attrs); + } + return principal; + } + aPrincipal = useOAForPrincipal(aPrincipal); + aTriggeringPrincipal = useOAForPrincipal(aTriggeringPrincipal); + if (!w || where == "window") { // Strip referrer data when opening a new private window, to prevent // regular browsing data from leaking into it. @@ -308,6 +327,7 @@ function openLinkIn(url, where, params) { sa.appendElement(referrerPolicySupports, /* weak =*/ false); sa.appendElement(userContextIdSupports, /* weak =*/ false); sa.appendElement(aPrincipal, /* weak =*/ false); + sa.appendElement(aTriggeringPrincipal, /* weak =*/ false); let features = "chrome,dialog=no,all"; if (aIsPrivate) { @@ -394,6 +414,7 @@ function openLinkIn(url, where, params) { } aCurrentBrowser.loadURIWithFlags(url, { + triggeringPrincipal: aTriggeringPrincipal, flags: flags, referrerURI: aNoReferrer ? null : aReferrerURI, referrerPolicy: aReferrerPolicy, @@ -419,6 +440,7 @@ function openLinkIn(url, where, params) { noReferrer: aNoReferrer, userContextId: aUserContextId, originPrincipal: aPrincipal, + triggeringPrincipal: aTriggeringPrincipal, }); browserUsedForLoad = tabUsedForLoad.linkedBrowser; break; diff --git a/browser/components/feeds/FeedConverter.js b/browser/components/feeds/FeedConverter.js index aa70620d4..c2c565608 100644 --- a/browser/components/feeds/FeedConverter.js +++ b/browser/components/feeds/FeedConverter.js @@ -264,7 +264,7 @@ FeedConverter.prototype = { } chromeChannel.loadGroup = this._request.loadGroup; - chromeChannel.asyncOpen(this._listener, null); + chromeChannel.asyncOpen2(this._listener); } finally { this._releaseHandles(); diff --git a/browser/components/sessionstore/ContentRestore.jsm b/browser/components/sessionstore/ContentRestore.jsm index 976016770..d4972bcaf 100644 --- a/browser/components/sessionstore/ContentRestore.jsm +++ b/browser/components/sessionstore/ContentRestore.jsm @@ -204,6 +204,9 @@ ContentRestoreInternal.prototype = { : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT); let postData = loadArguments.postData ? Utils.makeInputStream(loadArguments.postData) : null; + let triggeringPrincipal = loadArguments.triggeringPrincipal + ? Utils.deserializePrincipal(loadArguments.triggeringPrincipal) + : null; if (loadArguments.userContextId) { webNavigation.setOriginAttributesBeforeLoading({ userContextId: loadArguments.userContextId }); @@ -211,7 +214,7 @@ ContentRestoreInternal.prototype = { webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags, referrer, referrerPolicy, postData, - null, null); + null, null, triggeringPrincipal); } else if (tabData.userTypedValue && tabData.userTypedClear) { // If the user typed a URL into the URL bar and hit enter right before // we crashed, we want to start loading that page again. A non-zero diff --git a/browser/components/sessionstore/SessionHistory.jsm b/browser/components/sessionstore/SessionHistory.jsm index aa9c10379..3d28d87db 100644 --- a/browser/components/sessionstore/SessionHistory.jsm +++ b/browser/components/sessionstore/SessionHistory.jsm @@ -95,7 +95,10 @@ var SessionHistoryInternal = { // record it. For about:blank we explicitly want an empty array without // an 'index' property to denote that there are no history entries. if (uri != "about:blank" || (body && body.hasChildNodes())) { - data.entries.push({ url: uri }); + data.entries.push({ + url: uri, + triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL + }); data.index = 1; } } diff --git a/browser/components/sessionstore/SessionMigration.jsm b/browser/components/sessionstore/SessionMigration.jsm index ff339eba9..1aa22f1a9 100644 --- a/browser/components/sessionstore/SessionMigration.jsm +++ b/browser/components/sessionstore/SessionMigration.jsm @@ -11,6 +11,9 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); Cu.import("resource://gre/modules/Task.jsm", this); Cu.import("resource://gre/modules/osfile.jsm", this); +XPCOMUtils.defineLazyModuleGetter(this, "Utils", + "resource://gre/modules/sessionstore/Utils.jsm"); + // An encoder to UTF-8. XPCOMUtils.defineLazyGetter(this, "gEncoder", function () { return new TextEncoder(); @@ -27,7 +30,7 @@ var SessionMigrationInternal = { * only contain: * - open windows * - with tabs - * - with history entries with only title, url + * - with history entries with only title, url, triggeringPrincipal * - with pinned state * - with tab group info (hidden + group id) * - with selected tab info @@ -45,9 +48,11 @@ var SessionMigrationInternal = { var win = {extData: {}}; win.tabs = oldWin.tabs.map(function(oldTab) { var tab = {}; - // Keep only titles and urls for history entries + // Keep only titles, urls and triggeringPrincipals for history entries tab.entries = oldTab.entries.map(function(entry) { - return {url: entry.url, title: entry.title}; + return { url: entry.url, + triggeringPrincipal_base64: entry.triggeringPrincipal_base64, + title: entry.title }; }); tab.index = oldTab.index; tab.hidden = oldTab.hidden; @@ -60,7 +65,8 @@ var SessionMigrationInternal = { }); let url = "about:welcomeback"; let formdata = {id: {sessionData: state}, url}; - return {windows: [{tabs: [{entries: [{url}], formdata}]}]}; + let entry = { url, triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL }; + return { windows: [{ tabs: [{ entries: [ entry ], formdata}]}]}; }, /** * Asynchronously read session restore state (JSON) from a path diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm index 93e21357f..6b30943f3 100644 --- a/browser/components/sessionstore/SessionStore.jsm +++ b/browser/components/sessionstore/SessionStore.jsm @@ -603,12 +603,14 @@ var SessionStoreInternal = { // replace the crashed session with a restore-page-only session let url = "about:sessionrestore"; let formdata = {id: {sessionData: state}, url}; - state = { windows: [{ tabs: [{ entries: [{url}], formdata }] }] }; + let entry = {url, triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL }; + state = { windows: [{ tabs: [{ entries: [entry], formdata }] }] }; } else if (this._hasSingleTabWithURL(state.windows, "about:welcomeback")) { // On a single about:welcomeback URL that crashed, replace about:welcomeback // with about:sessionrestore, to make clear to the user that we crashed. state.windows[0].tabs[0].entries[0].url = "about:sessionrestore"; + state.windows[0].tabs[0].entries[0].triggeringPrincipal_base64 = Utils.SERIALIZED_SYSTEMPRINCIPAL; } } diff --git a/browser/modules/ContentClick.jsm b/browser/modules/ContentClick.jsm index 8abc32525..40101d5d3 100644 --- a/browser/modules/ContentClick.jsm +++ b/browser/modules/ContentClick.jsm @@ -85,6 +85,7 @@ var ContentClick = { allowMixedContent: json.allowMixedContent, isContentWindowPrivate: json.isContentWindowPrivate, originPrincipal: json.originPrincipal, + triggeringPrincipal: json.triggeringPrincipal, }; // The new tab/window must use the same userContextId. |