Bug 1722050 - Add policy for opening executable files based on domain/extension pairs. r=Gijs,fluent-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D144214
This commit is contained in:
Mike Kaply 2022-05-12 13:17:30 +00:00
Родитель 5b655b243e
Коммит 523416b7fb
8 изменённых файлов: 131 добавлений и 0 удалений

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

@ -986,6 +986,11 @@ var Policies = {
},
},
ExemptDomainFileTypePairsFromFileTypeDownloadWarnings: {
// This policy is handled directly in EnterprisePoliciesParent.jsm
// and requires no validation (It's done by the schema).
},
ExtensionSettings: {
onBeforeAddons(manager, param) {
try {

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

@ -461,6 +461,24 @@
}
},
"ExemptDomainFileTypePairsFromFileTypeDownloadWarnings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"file_extension": {
"type": "string"
},
"domains": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"Extensions": {
"type": "object",
"properties": {

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

@ -0,0 +1,66 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_exempt_xxx() {
await setupPolicyEngineWithJson({
policies: {
ExemptDomainFileTypePairsFromFileTypeDownloadWarnings: [
{
file_extension: "jnlp",
domains: ["example.com", "www.example.edu"],
},
],
},
});
equal(
Services.policies.isExemptExecutableExtension(
"https://www.example.edu",
"jnlp"
),
true
);
equal(
Services.policies.isExemptExecutableExtension(
"https://example.edu",
"jnlp"
),
false
);
equal(
Services.policies.isExemptExecutableExtension(
"https://example.com",
"jnlp"
),
true
);
equal(
Services.policies.isExemptExecutableExtension(
"https://www.example.com",
"jnlp"
),
true
);
equal(
Services.policies.isExemptExecutableExtension(
"https://wwwexample.com",
"jnlp"
),
false
);
equal(
Services.policies.isExemptExecutableExtension(
"https://www.example.org",
"jnlp"
),
false
);
equal(
Services.policies.isExemptExecutableExtension(
"https://www.example.edu",
"exe"
),
false
);
});

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

@ -13,6 +13,7 @@ support-files =
[test_clear_blocked_cookies.js]
[test_defaultbrowsercheck.js]
[test_empty_policy.js]
[test_exempt_domain_file_type_pairs_from_file_type_download_warnings.js]
[test_extensions.js]
[test_extensionsettings.js]
[test_macosparser_unflatten.js]

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

@ -102,6 +102,8 @@ policy-EnableTrackingProtection = Enable or disable Content Blocking and optiona
# “lock” means that the user wont be able to change this setting
policy-EncryptedMediaExtensions = Enable or disable Encrypted Media Extensions and optionally lock it.
policy-ExemptDomainFileTypePairsFromFileTypeDownloadWarnings = Disable warnings based on file extension for specific file types on domains.
# A “locked” extension cant be disabled or removed by the user. This policy
# takes 3 keys (“Install”, ”Uninstall”, ”Locked”), you can either keep them in
# English or translate them as verbs.

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

@ -734,6 +734,17 @@ var DownloadIntegration = {
fileExtension &&
fileExtension.toLowerCase() == "exe";
let isExemptExecutableExtension = false;
try {
let url = new URL(aDownload.source.url);
isExemptExecutableExtension = Services.policies.isExemptExecutableExtension(
url.origin,
fileExtension?.toLowerCase()
);
} catch (e) {
// Invalid URL, go down the original path.
}
// Ask for confirmation if the file is executable, except for .exe on
// Windows where the operating system will show the prompt based on the
// security zone. We do this here, instead of letting the caller handle
@ -741,9 +752,11 @@ var DownloadIntegration = {
// first is because of its security nature, so that add-ons cannot forget
// to do this check. The second is that the system-level security prompt
// would be displayed at launch time in any case.
// We allow policy to override this behavior for file extensions on specific domains.
if (
file.isExecutable() &&
!isWindowsExe &&
!isExemptExecutableExtension &&
!(await this.confirmLaunchExecutable(file.path))
) {
return;

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

@ -427,6 +427,25 @@ EnterprisePoliciesManager.prototype = {
allowedInstallSource(uri) {
return InstallSources ? InstallSources.matches(uri) : true;
},
isExemptExecutableExtension(origin, extension) {
let hostname = new URL(origin)?.hostname;
let exemptArray = this.getActivePolicies()
?.ExemptDomainFileTypePairsFromFileTypeDownloadWarnings;
if (!hostname || !extension || !exemptArray) {
return false;
}
let domains = exemptArray
.filter(item => item.file_extension == extension)
.map(item => item.domains)
.flat();
for (let domain of domains) {
if (Services.eTLD.hasRootDomain(hostname, domain)) {
return true;
}
}
return false;
},
};
let DisallowedFeatures = {};

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

@ -65,4 +65,11 @@ interface nsIEnterprisePolicies : nsISupports
* @returns A boolean - true of the extension may be installed.
*/
bool allowedInstallSource(in nsIURI uri);
/**
* Uses ExemptDomainFileTypePairsFromFileTypeDownloadWarnings to determine
* if a given file extension is exempted from executable warnings.
*
* @returns A boolean - true if warnings should not be shown.
*/
bool isExemptExecutableExtension(in ACString origin, in ACString extension);
};