зеркало из https://github.com/mozilla/gecko-dev.git
Bug 950417 - Enable safe direct request add-on installs. r=wesj, r=Mossop
This commit is contained in:
Родитель
efe59c5d9b
Коммит
a206a9418d
|
@ -170,6 +170,8 @@ pref("dom.experimental_forms", true);
|
||||||
pref("dom.forms.number", true);
|
pref("dom.forms.number", true);
|
||||||
|
|
||||||
/* extension manager and xpinstall */
|
/* extension manager and xpinstall */
|
||||||
|
pref("xpinstall.whitelist.directRequest", false);
|
||||||
|
pref("xpinstall.whitelist.fileRequest", false);
|
||||||
pref("xpinstall.whitelist.add", "addons.mozilla.org");
|
pref("xpinstall.whitelist.add", "addons.mozilla.org");
|
||||||
pref("xpinstall.whitelist.add.180", "marketplace.firefox.com");
|
pref("xpinstall.whitelist.add.180", "marketplace.firefox.com");
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,25 @@
|
||||||
<action android:name="android.intent.action.SEARCH" />
|
<action android:name="android.intent.action.SEARCH" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
|
<!-- For XPI installs from websites and the download manager. -->
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:scheme="file" />
|
||||||
|
<data android:scheme="http" />
|
||||||
|
<data android:scheme="https" />
|
||||||
|
<data android:mimeType="application/x-xpinstall" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<!-- For XPI installs from file: URLs. -->
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:host="" />
|
||||||
|
<data android:scheme="file" />
|
||||||
|
<data android:pathPattern=".*\\.xpi" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
#ifdef MOZ_ANDROID_BEAM
|
#ifdef MOZ_ANDROID_BEAM
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
|
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
|
||||||
|
|
|
@ -5695,7 +5695,10 @@ var XPInstallObserver = {
|
||||||
if (!tab)
|
if (!tab)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let host = installInfo.originatingURI.host;
|
let host = null;
|
||||||
|
if (installInfo.originatingURI) {
|
||||||
|
host = installInfo.originatingURI.host;
|
||||||
|
}
|
||||||
|
|
||||||
let brandShortName = Strings.brand.GetStringFromName("brandShortName");
|
let brandShortName = Strings.brand.GetStringFromName("brandShortName");
|
||||||
let notificationName, buttons, message;
|
let notificationName, buttons, message;
|
||||||
|
@ -5723,7 +5726,23 @@ var XPInstallObserver = {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
notificationName = "xpinstall";
|
notificationName = "xpinstall";
|
||||||
message = strings.formatStringFromName("xpinstallPromptWarning2", [brandShortName, host], 2);
|
if (host) {
|
||||||
|
// We have a host which asked for the install.
|
||||||
|
message = strings.formatStringFromName("xpinstallPromptWarning2", [brandShortName, host], 2);
|
||||||
|
} else {
|
||||||
|
// Without a host we address the add-on as the initiator of the install.
|
||||||
|
let addon = null;
|
||||||
|
if (installInfo.installs.length > 0) {
|
||||||
|
addon = installInfo.installs[0].name;
|
||||||
|
}
|
||||||
|
if (addon) {
|
||||||
|
// We have an addon name, show the regular message.
|
||||||
|
message = strings.formatStringFromName("xpinstallPromptWarningLocal", [brandShortName, addon], 2);
|
||||||
|
} else {
|
||||||
|
// We don't have an addon name, show an alternative message.
|
||||||
|
message = strings.formatStringFromName("xpinstallPromptWarningDirect", [brandShortName], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buttons = [{
|
buttons = [{
|
||||||
label: strings.GetStringFromName("xpinstallPromptAllowButton"),
|
label: strings.GetStringFromName("xpinstallPromptAllowButton"),
|
||||||
|
|
|
@ -71,6 +71,8 @@ blockPopups.label=Block Popups
|
||||||
|
|
||||||
# XPInstall
|
# XPInstall
|
||||||
xpinstallPromptWarning2=%S prevented this site (%S) from asking you to install software on your device.
|
xpinstallPromptWarning2=%S prevented this site (%S) from asking you to install software on your device.
|
||||||
|
xpinstallPromptWarningLocal=%S prevented this add-on (%S) from installing on your device.
|
||||||
|
xpinstallPromptWarningDirect=%S prevented an add-on from installing on your device.
|
||||||
xpinstallPromptAllowButton=Allow
|
xpinstallPromptAllowButton=Allow
|
||||||
xpinstallDisabledMessageLocked=Software installation has been disabled by your system administrator.
|
xpinstallDisabledMessageLocked=Software installation has been disabled by your system administrator.
|
||||||
xpinstallDisabledMessage2=Software installation is currently disabled. Press Enable and try again.
|
xpinstallDisabledMessage2=Software installation is currently disabled. Press Enable and try again.
|
||||||
|
|
|
@ -67,6 +67,8 @@ const PREF_EM_AUTO_DISABLED_SCOPES = "extensions.autoDisableScopes";
|
||||||
const PREF_EM_SHOW_MISMATCH_UI = "extensions.showMismatchUI";
|
const PREF_EM_SHOW_MISMATCH_UI = "extensions.showMismatchUI";
|
||||||
const PREF_XPI_ENABLED = "xpinstall.enabled";
|
const PREF_XPI_ENABLED = "xpinstall.enabled";
|
||||||
const PREF_XPI_WHITELIST_REQUIRED = "xpinstall.whitelist.required";
|
const PREF_XPI_WHITELIST_REQUIRED = "xpinstall.whitelist.required";
|
||||||
|
const PREF_XPI_DIRECT_WHITELISTED = "xpinstall.whitelist.directRequest";
|
||||||
|
const PREF_XPI_FILE_WHITELISTED = "xpinstall.whitelist.fileRequest";
|
||||||
const PREF_XPI_PERMISSIONS_BRANCH = "xpinstall.";
|
const PREF_XPI_PERMISSIONS_BRANCH = "xpinstall.";
|
||||||
const PREF_XPI_UNPACK = "extensions.alwaysUnpack";
|
const PREF_XPI_UNPACK = "extensions.alwaysUnpack";
|
||||||
const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts";
|
const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts";
|
||||||
|
@ -3445,6 +3447,28 @@ var XPIProvider = {
|
||||||
return Prefs.getBoolPref(PREF_XPI_ENABLED, true);
|
return Prefs.getBoolPref(PREF_XPI_ENABLED, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to test whether installing XPI add-ons by direct URL requests is
|
||||||
|
* whitelisted.
|
||||||
|
*
|
||||||
|
* @return true if installing by direct requests is whitelisted
|
||||||
|
*/
|
||||||
|
isDirectRequestWhitelisted: function XPI_isDirectRequestWhitelisted() {
|
||||||
|
// Default to whitelisted if the preference does not exist.
|
||||||
|
return Prefs.getBoolPref(PREF_XPI_DIRECT_WHITELISTED, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to test whether installing XPI add-ons from file referrers is
|
||||||
|
* whitelisted.
|
||||||
|
*
|
||||||
|
* @return true if installing from file referrers is whitelisted
|
||||||
|
*/
|
||||||
|
isFileRequestWhitelisted: function XPI_isFileRequestWhitelisted() {
|
||||||
|
// Default to whitelisted if the preference does not exist.
|
||||||
|
return Prefs.getBoolPref(PREF_XPI_FILE_WHITELISTED, true);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to test whether installing XPI add-ons from a URI is allowed.
|
* Called to test whether installing XPI add-ons from a URI is allowed.
|
||||||
*
|
*
|
||||||
|
@ -3456,11 +3480,13 @@ var XPIProvider = {
|
||||||
if (!this.isInstallEnabled())
|
if (!this.isInstallEnabled())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Direct requests without a referrer are either whitelisted or blocked.
|
||||||
if (!aUri)
|
if (!aUri)
|
||||||
return true;
|
return this.isDirectRequestWhitelisted();
|
||||||
|
|
||||||
// file: and chrome: don't need whitelisted hosts
|
// Local referrers can be whitelisted.
|
||||||
if (aUri.schemeIs("chrome") || aUri.schemeIs("file"))
|
if (this.isFileRequestWhitelisted() &&
|
||||||
|
(aUri.schemeIs("chrome") || aUri.schemeIs("file")))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
this.importPermissions();
|
this.importPermissions();
|
||||||
|
|
|
@ -62,6 +62,8 @@ support-files =
|
||||||
[browser_installchrome.js]
|
[browser_installchrome.js]
|
||||||
[browser_localfile.js]
|
[browser_localfile.js]
|
||||||
[browser_localfile2.js]
|
[browser_localfile2.js]
|
||||||
|
[browser_localfile3.js]
|
||||||
|
[browser_localfile4.js]
|
||||||
[browser_multipackage.js]
|
[browser_multipackage.js]
|
||||||
[browser_navigateaway.js]
|
[browser_navigateaway.js]
|
||||||
[browser_navigateaway2.js]
|
[browser_navigateaway2.js]
|
||||||
|
@ -84,3 +86,4 @@ support-files =
|
||||||
[browser_whitelist4.js]
|
[browser_whitelist4.js]
|
||||||
[browser_whitelist5.js]
|
[browser_whitelist5.js]
|
||||||
[browser_whitelist6.js]
|
[browser_whitelist6.js]
|
||||||
|
[browser_whitelist7.js]
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Tests installing an add-on from a local file with whitelisting disabled.
|
||||||
|
// This should be blocked by the whitelist check.
|
||||||
|
function test() {
|
||||||
|
Harness.installBlockedCallback = allow_blocked;
|
||||||
|
Harness.installsCompletedCallback = finish_test;
|
||||||
|
Harness.setup();
|
||||||
|
|
||||||
|
// Disable direct request whitelisting, installing from file should be blocked.
|
||||||
|
Services.prefs.setBoolPref("xpinstall.whitelist.directRequest", false);
|
||||||
|
|
||||||
|
var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
|
||||||
|
.getService(Components.interfaces.nsIChromeRegistry);
|
||||||
|
|
||||||
|
var chromeroot = extractChromeRoot(gTestPath);
|
||||||
|
try {
|
||||||
|
var xpipath = cr.convertChromeURL(makeURI(chromeroot + "unsigned.xpi")).spec;
|
||||||
|
} catch (ex) {
|
||||||
|
var xpipath = chromeroot + "unsigned.xpi"; //scenario where we are running from a .jar and already extracted
|
||||||
|
}
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.loadURI(xpipath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function allow_blocked(installInfo) {
|
||||||
|
ok(true, "Seen blocked");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish_test(count) {
|
||||||
|
is(count, 0, "No add-ons should have been installed");
|
||||||
|
|
||||||
|
Services.prefs.clearUserPref("xpinstall.whitelist.directRequest");
|
||||||
|
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
Harness.finish();
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Tests installing an add-on from a local file with whitelisting disabled.
|
||||||
|
// This should be blocked by the whitelist check.
|
||||||
|
function test() {
|
||||||
|
Harness.installBlockedCallback = allow_blocked;
|
||||||
|
Harness.installsCompletedCallback = finish_test;
|
||||||
|
Harness.setup();
|
||||||
|
|
||||||
|
// Disable file request whitelisting, installing by file referrer should be blocked.
|
||||||
|
Services.prefs.setBoolPref("xpinstall.whitelist.fileRequest", false);
|
||||||
|
|
||||||
|
var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
|
||||||
|
.getService(Components.interfaces.nsIChromeRegistry);
|
||||||
|
|
||||||
|
var chromeroot = extractChromeRoot(gTestPath);
|
||||||
|
try {
|
||||||
|
var xpipath = cr.convertChromeURL(makeURI(chromeroot)).spec;
|
||||||
|
} catch (ex) {
|
||||||
|
var xpipath = chromeroot; //scenario where we are running from a .jar and already extracted
|
||||||
|
}
|
||||||
|
var triggers = encodeURIComponent(JSON.stringify({
|
||||||
|
"Unsigned XPI": TESTROOT + "unsigned.xpi"
|
||||||
|
}));
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.loadURI(xpipath + "installtrigger.html?" + triggers);
|
||||||
|
}
|
||||||
|
|
||||||
|
function allow_blocked(installInfo) {
|
||||||
|
ok(true, "Seen blocked");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish_test(count) {
|
||||||
|
is(count, 0, "No add-ons should have been installed");
|
||||||
|
|
||||||
|
Services.prefs.clearUserPref("xpinstall.whitelist.fileRequest");
|
||||||
|
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
Harness.finish();
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Tests installing an unsigned add-on through a direct install request from
|
||||||
|
// web content. This should be blocked by the whitelist check because we disable
|
||||||
|
// direct request whitelisting, even though the target URI is whitelisted.
|
||||||
|
function test() {
|
||||||
|
Harness.installBlockedCallback = allow_blocked;
|
||||||
|
Harness.installsCompletedCallback = finish_test;
|
||||||
|
Harness.setup();
|
||||||
|
|
||||||
|
// Disable direct request whitelisting, installing should be blocked.
|
||||||
|
Services.prefs.setBoolPref("xpinstall.whitelist.directRequest", false);
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.loadURI(TESTROOT + "unsigned.xpi");
|
||||||
|
}
|
||||||
|
|
||||||
|
function allow_blocked(installInfo) {
|
||||||
|
ok(true, "Seen blocked");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish_test(count) {
|
||||||
|
is(count, 0, "No add-ons should have been installed");
|
||||||
|
|
||||||
|
Services.perms.remove("example.org", "install");
|
||||||
|
Services.prefs.clearUserPref("xpinstall.whitelist.directRequest");
|
||||||
|
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
Harness.finish();
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче