Merge branch 'MDL-69050-310-allowlist' of git://github.com/mudrd8mz/moodle into MOODLE_310_STABLE

This commit is contained in:
Sara Arjona 2020-10-01 14:51:12 +02:00
commit 7db1a61a72
36 changed files with 381 additions and 271 deletions

View file

@ -38,17 +38,17 @@ if ($unrecognized) {
}
// If necessary add files that should be ignored - such as in 3rd party plugins.
$blacklist = array();
$ignorelist = array();
$path = $options['path'];
if (!file_exists($path)) {
cli_error("Invalid path $path");
}
if ($options['ie9fix']) {
core_admin_recurse_svgs($path, '', 'core_admin_svgtool_ie9fix', $blacklist);
core_admin_recurse_svgs($path, '', 'core_admin_svgtool_ie9fix', $ignorelist);
} else if ($options['noaspectratio']) {
core_admin_recurse_svgs($path, '', 'core_admin_svgtool_noaspectratio', $blacklist);
core_admin_recurse_svgs($path, '', 'core_admin_svgtool_noaspectratio', $ignorelist);
} else {
$help =
@ -153,9 +153,9 @@ function core_admin_svgtool_noaspectratio($file) {
* @param string $base
* @param string $sub
* @param string $filecallback
* @param array $blacklist
* @param array $ignorelist List of files to be ignored and skipped.
*/
function core_admin_recurse_svgs($base, $sub, $filecallback, $blacklist) {
function core_admin_recurse_svgs($base, $sub, $filecallback, $ignorelist) {
if (is_dir("$base/$sub")) {
$items = new DirectoryIterator("$base/$sub");
foreach ($items as $item) {
@ -163,7 +163,7 @@ function core_admin_recurse_svgs($base, $sub, $filecallback, $blacklist) {
continue;
}
$file = $item->getFilename();
core_admin_recurse_svgs("$base/$sub", $file, $filecallback, $blacklist);
core_admin_recurse_svgs("$base/$sub", $file, $filecallback, $ignorelist);
}
unset($item);
unset($items);
@ -174,7 +174,7 @@ function core_admin_recurse_svgs($base, $sub, $filecallback, $blacklist) {
return;
}
$file = realpath("$base/$sub");
if (in_array($file, $blacklist)) {
if (in_array($file, $ignorelist)) {
return;
}
$filecallback($file);

View file

@ -142,7 +142,7 @@ function tool_dbtransfer_get_drivers() {
$dblibrary = $matches[2];
if ($dbtype === 'sqlite3') {
// Blacklist unfinished drivers.
// The sqlite3 driver is not fully working yet and should not be returned.
continue;
}

View file

@ -61,7 +61,7 @@ foreach ($allfunctions as $f) {
}
}
// whitelisting security
// Allow only functions available for testing.
if (!isset($functions[$function])) {
$function = '';
}
@ -81,7 +81,9 @@ foreach ($active_protocols as $p) {
}
$protocols[$p] = get_string('pluginname', 'webservice_'.$p);
}
if (!isset($protocols[$protocol])) { // whitelisting security
// Allow only protocols supporting the test client.
if (!isset($protocols[$protocol])) {
$protocol = '';
}

View file

@ -3273,7 +3273,7 @@ function calendar_get_calendar_context($subscription) {
}
/**
* Implements callback user_preferences, whitelists preferences that users are allowed to update directly
* Implements callback user_preferences, lists preferences that users are allowed to update directly
*
* Used in {@see core_user::fill_preferences_cache()}, see also {@see useredit_update_user_preference()}
*

View file

@ -227,7 +227,8 @@ class filter_algebra extends moodle_text_filter {
$texexp = preg_replace('/\\\int\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\int_'. "{\$2}^{\$3}\$1 ",$texexp);
$texexp = preg_replace('/\\\int\\\left\((.+?d[a-z])\\\right\)/s','\int '. "\$1 ",$texexp);
$texexp = preg_replace('/\\\lim\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\lim_'. "{\$2\\to \$3}\$1 ",$texexp);
$texexp = str_replace('\mbox', '', $texexp); // now blacklisted in tex, sorry
// Remove a forbidden keyword.
$texexp = str_replace('\mbox', '', $texexp);
$texcache = new stdClass();
$texcache->filter = 'algebra';
$texcache->version = 1;

View file

@ -59,9 +59,17 @@ function filter_tex_get_executable($debug=false) {
print_error('mimetexisnotexist', 'error');
}
function filter_tex_sanitize_formula($texexp) {
/// Check $texexp against blacklist (whitelisting could be more complete but also harder to maintain)
$tex_blacklist = array(
/**
* Check the formula expression against the list of denied keywords.
*
* List of allowed could be more complete but also harder to maintain.
*
* @param string $texexp Formula expression to check.
* @return string Formula expression with denied keywords replaced with 'forbiddenkeyword'.
*/
function filter_tex_sanitize_formula(string $texexp): string {
$denylist = [
'include', 'command', 'loop', 'repeat', 'open', 'toks', 'output',
'input', 'catcode', 'name', '^^',
'\def', '\edef', '\gdef', '\xdef',
@ -70,10 +78,10 @@ function filter_tex_sanitize_formula($texexp) {
'\lowercase', '\relax', '\aftergroup',
'\afterassignment', '\expandafter', '\noexpand', '\special',
'\let', '\futurelet', '\else', '\fi', '\chardef', '\makeatletter', '\afterground',
'\noexpand','\line','\mathcode','\item','\section','\mbox','\declarerobustcommand'
);
'\noexpand', '\line', '\mathcode', '\item', '\section', '\mbox', '\declarerobustcommand',
];
return str_ireplace($tex_blacklist, 'forbiddenkeyword', $texexp);
return str_ireplace($denylist, 'forbiddenkeyword', $texexp);
}
function filter_tex_get_cmd($pathname, $texexp) {

View file

@ -122,3 +122,4 @@ availablelicenses,core_admin
managelicenses,core_admin
userfilterplaceholder,core
sitebackpackverify,core_badges
filetypesnotwhitelisted,core_form

View file

@ -42,11 +42,11 @@ $string['err_numeric'] = 'You must enter a number here.';
$string['err_rangelength'] = 'You must enter between {$a->format[0]} and {$a->format[1]} characters here.';
$string['err_required'] = 'You must supply a value here.';
$string['err_wrappingwhitespace'] = 'The value must not start or end with whitespace.';
$string['err_wrongfileextension'] = 'Some files ({$a->wrongfiles}) cannot be uploaded. Only file types {$a->whitelist} are allowed.';
$string['err_wrongfileextension'] = 'Some files ({$a->wrongfiles}) cannot be uploaded. Only file types {$a->allowlist} are allowed.';
$string['filesofthesetypes'] = 'Accepted file types:';
$string['filetypesany'] = 'All file types';
$string['filetypesnotall'] = 'It is not allowed to select \'All file types\' here';
$string['filetypesnotwhitelisted'] = 'These file types are not allowed here: {$a}';
$string['filetypesnotallowed'] = 'These file types are not allowed here: {$a}';
$string['filetypesothers'] = 'Other files';
$string['filetypesunknown'] = 'Unknown file types: {$a}';
$string['general'] = 'General';
@ -85,3 +85,6 @@ $string['timeunit'] = 'Time unit';
$string['timing'] = 'Timing';
$string['unmaskpassword'] = 'Unmask';
$string['year'] = 'Year';
// Deprecated since Moodle 3.10.
$string['filetypesnotwhitelisted'] = 'These file types are not allowed here: {$a}';

View file

@ -9071,7 +9071,7 @@ function any_new_admin_settings($node) {
*/
function db_should_replace($table, $column = ''): bool {
// TODO: this is horrible hack, we should do whitelisting and each plugin should be responsible for proper replacing...
// TODO: this is horrible hack, we should have a hook and each plugin should be responsible for proper replacing...
$skiptables = ['config', 'config_plugins', 'filter_config', 'sessions',
'events_queue', 'repository_instance_config', 'block_instances', 'files'];
@ -11271,12 +11271,12 @@ class admin_setting_filetypes extends admin_setting_configtext {
// No need to call parent's validation here as we are PARAM_RAW.
if ($this->util->is_whitelisted($data, $this->onlytypes)) {
if ($this->util->is_listed($data, $this->onlytypes)) {
return true;
} else {
$troublemakers = $this->util->get_not_whitelisted($data, $this->onlytypes);
return get_string('filetypesnotwhitelisted', 'core_form', implode(' ', $troublemakers));
$troublemakers = $this->util->get_not_listed($data, $this->onlytypes);
return get_string('filetypesnotallowed', 'core_form', implode(' ', $troublemakers));
}
}

File diff suppressed because one or more lines are too long

View file

@ -65,8 +65,8 @@ define([
/** @var {Bool} isLoadingTemplates - Whether templates are currently being loaded */
var isLoadingTemplates = false;
/** @var {Array} blacklistedNestedHelpers - List of helpers that can't be called within other helpers */
var blacklistedNestedHelpers = ['js'];
/** @var {Array} disallowedNestedHelpers - List of helpers that can't be called within other helpers */
var disallowedNestedHelpers = ['js'];
/**
* Search the various caches for a template promise for the given search key.
@ -609,7 +609,7 @@ define([
* template.
*
* This will parse the provided text before giving it to the helper function
* in order to remove any blacklisted nested helpers to prevent one helper
* in order to remove any disallowed nested helpers to prevent one helper
* from calling another.
*
* In particular to prevent the JS helper from being called from within another
@ -623,12 +623,12 @@ define([
Renderer.prototype.addHelperFunction = function(helperFunction, context) {
return function() {
return function(sectionText, helper) {
// Override the blacklisted helpers in the template context with
// Override the disallowed helpers in the template context with
// a function that returns an empty string for use when executing
// other helpers. This is to prevent these helpers from being
// executed as part of the rendering of another helper in order to
// prevent any potential security issues.
var originalHelpers = blacklistedNestedHelpers.reduce(function(carry, name) {
var originalHelpers = disallowedNestedHelpers.reduce(function(carry, name) {
if (context.hasOwnProperty(name)) {
carry[name] = context[name];
}
@ -636,14 +636,14 @@ define([
return carry;
}, {});
blacklistedNestedHelpers.forEach(function(helperName) {
disallowedNestedHelpers.forEach(function(helperName) {
context[helperName] = function() {
return '';
};
});
// Execute the helper with the modified context that doesn't include
// the blacklisted nested helpers. This prevents the blacklisted
// the disallowed nested helpers. This prevents the disallowed
// helpers from being called from within other helpers.
var result = helperFunction.apply(this, [context, sectionText, helper]);

View file

@ -733,7 +733,7 @@ $cache = '.var_export($cache, true).';
/**
* List all core subsystems and their location
*
* This is a whitelist of components that are part of the core and their
* This is a list of components that are part of the core and their
* language strings are defined in /lang/en/<<subsystem>>.php. If a given
* plugin is not listed here and it does not have proper plugintype prefix,
* then it is considered as course activity module.

View file

@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Contains a class providing functions used to check the host/port black/whitelists for curl.
* Contains a class providing functions used to check the allowed/blocked host/ports for curl.
*
* @package core
* @copyright 2016 Jake Dallimore
@ -32,7 +32,7 @@ defined('MOODLE_INTERNAL') || exit();
* Host and port checking for curl.
*
* This class provides a means to check URL/host/port against the system-level cURL security entries.
* It does not provide a means to add URLs, hosts or ports to the black/white lists; this is configured manually
* It does not provide a means to add URLs, hosts or ports to the allowed/blocked lists; this is configured manually
* via the site admin section of Moodle (See: 'Site admin' > 'Security' > 'HTTP Security').
*
* This class is currently used by the 'curl' wrapper class in lib/filelib.php.
@ -55,12 +55,12 @@ class curl_security_helper extends curl_security_helper_base {
];
/**
* Checks whether the given URL is blacklisted by checking its address and port number against the black/white lists.
* Checks whether the given URL is blocked by checking its address and port number against the allow/block lists.
* The behaviour of this function can be classified as strict, as it returns true for URLs which are invalid or
* could not be parsed, as well as those valid URLs which were found in the blacklist.
* could not be parsed, as well as those valid URLs which were found in the blocklist.
*
* @param string $urlstring the URL to check.
* @return bool true if the URL is blacklisted or invalid and false if the URL is not blacklisted.
* @return bool true if the URL is blocked or invalid and false if the URL is not blocked.
*/
public function url_is_blocked($urlstring) {
// If no config data is present, then all hosts/ports are allowed.
@ -85,7 +85,7 @@ class curl_security_helper extends curl_security_helper_base {
}
if ($parsed['port'] && $parsed['host']) {
// Check the host and port against the blacklist/whitelist entries.
// Check the host and port against the allow/block entries.
return $this->host_is_blocked($parsed['host']) || $this->port_is_blocked($parsed['port']);
}
return true;
@ -114,9 +114,9 @@ class curl_security_helper extends curl_security_helper_base {
* - This will perform a DNS reverse lookup if required.
*
* The behaviour of this function can be classified as strict, as it returns true for hosts which are invalid or
* could not be parsed, as well as those valid URLs which were found in the blacklist.
* could not be parsed, as well as those valid URLs which were found in the blocklist.
*
* @param string $host the host component of the URL to check against the blacklist.
* @param string $host the host component of the URL to check against the blocklist.
* @return bool true if the host is both valid and blocked, false otherwise.
*/
protected function host_is_blocked($host) {
@ -126,7 +126,7 @@ class curl_security_helper extends curl_security_helper_base {
// Fix for square brackets in the 'host' portion of the URL (only occurs if an IPv6 address is specified).
$host = str_replace(array('[', ']'), '', $host); // RFC3986, section 3.2.2.
$blacklistedhosts = $this->get_blacklisted_hosts_by_category();
$blockedhosts = $this->get_blocked_hosts_by_category();
if (ip_utils::is_ip_address($host)) {
if ($this->address_explicitly_blocked($host)) {
@ -134,7 +134,7 @@ class curl_security_helper extends curl_security_helper_base {
}
// Only perform a reverse lookup if there is a point to it (i.e. we have rules to check against).
if ($blacklistedhosts['domain'] || $blacklistedhosts['domainwildcard']) {
if ($blockedhosts['domain'] || $blockedhosts['domainwildcard']) {
// DNS reverse lookup - supports both IPv4 and IPv6 address formats.
$hostname = gethostbyaddr($host);
if ($hostname !== $host && $this->host_explicitly_blocked($hostname)) {
@ -147,7 +147,7 @@ class curl_security_helper extends curl_security_helper_base {
}
// Only perform a forward lookup if there are IP rules to check against.
if ($blacklistedhosts['ipv4'] || $blacklistedhosts['ipv6']) {
if ($blockedhosts['ipv4'] || $blockedhosts['ipv6']) {
// DNS forward lookup - returns a list of only IPv4 addresses!
$hostips = $this->get_host_list_by_name($host);
@ -156,7 +156,7 @@ class curl_security_helper extends curl_security_helper_base {
return true;
}
// If any of the returned IPs are in the blacklist, block the request.
// If any of the returned IPs are in the blocklist, block the request.
foreach ($hostips as $hostip) {
if ($this->address_explicitly_blocked($hostip)) {
return true;
@ -182,10 +182,10 @@ class curl_security_helper extends curl_security_helper_base {
}
/**
* Checks whether the given port is blocked, as determined by its absence on the ports whitelist.
* Ports are assumed to be blocked unless found in the whitelist.
* Checks whether the given port is blocked, as determined by its absence on the ports allowlist.
* Ports are assumed to be blocked unless found in the allowlist.
*
* @param integer|string $port the port to check against the ports whitelist.
* @param integer|string $port the port to check against the ports allowlist.
* @return bool true if the port is blocked, false otherwise.
*/
protected function port_is_blocked($port) {
@ -194,28 +194,28 @@ class curl_security_helper extends curl_security_helper_base {
if (empty($port) || (string)$portnum !== (string)$port || $port < 0) {
return true;
}
$allowedports = $this->get_whitelisted_ports();
$allowedports = $this->get_allowed_ports();
return !empty($allowedports) && !in_array($portnum, $allowedports);
}
/**
* Convenience method to check whether we have any entries in the host blacklist or ports whitelist admin settings.
* If no entries are found at all, the assumption is that the blacklist is disabled entirely.
* Convenience method to check whether we have any entries in the host blocklist or ports allowlist admin settings.
* If no entries are found at all, the assumption is that the blocklist is disabled entirely.
*
* @return bool true if one or more entries exist, false otherwise.
*/
public function is_enabled() {
return (!empty($this->get_whitelisted_ports()) || !empty($this->get_blacklisted_hosts()));
return (!empty($this->get_allowed_ports()) || !empty($this->get_blocked_hosts()));
}
/**
* Checks whether the input address is blocked by at any of the IPv4 or IPv6 address rules.
*
* @param string $addr the ip address to check.
* @return bool true if the address is covered by an entry in the blacklist, false otherwise.
* @return bool true if the address is covered by an entry in the blocklist, false otherwise.
*/
protected function address_explicitly_blocked($addr) {
$blockedhosts = $this->get_blacklisted_hosts_by_category();
$blockedhosts = $this->get_blocked_hosts_by_category();
$iphostsblocked = array_merge($blockedhosts['ipv4'], $blockedhosts['ipv6']);
return address_in_subnet($addr, implode(',', $iphostsblocked));
}
@ -224,10 +224,10 @@ class curl_security_helper extends curl_security_helper_base {
* Checks whether the input hostname is blocked by any of the domain/wildcard rules.
*
* @param string $host the hostname to check
* @return bool true if the host is covered by an entry in the blacklist, false otherwise.
* @return bool true if the host is covered by an entry in the blocklist, false otherwise.
*/
protected function host_explicitly_blocked($host) {
$blockedhosts = $this->get_blacklisted_hosts_by_category();
$blockedhosts = $this->get_blocked_hosts_by_category();
$domainhostsblocked = array_merge($blockedhosts['domain'], $blockedhosts['domainwildcard']);
return ip_utils::is_domain_in_allowed_list($host, $domainhostsblocked);
}
@ -238,10 +238,10 @@ class curl_security_helper extends curl_security_helper_base {
*
* @return array of host/domain/ip entries from the 'curlsecurityblockedhosts' config.
*/
protected function get_blacklisted_hosts_by_category() {
protected function get_blocked_hosts_by_category() {
// For each of the admin setting entries, check and place in the correct section of the config array.
$config = ['ipv6' => [], 'ipv4' => [], 'domain' => [], 'domainwildcard' => []];
$entries = $this->get_blacklisted_hosts();
$entries = $this->get_blocked_hosts();
foreach ($entries as $entry) {
if (ip_utils::is_ipv6_address($entry) || ip_utils::is_ipv6_range($entry)) {
$config['ipv6'][] = $entry;
@ -257,11 +257,11 @@ class curl_security_helper extends curl_security_helper_base {
}
/**
* Helper that returns the whitelisted ports, as defined in the 'curlsecurityallowedport' setting.
* Helper that returns the allowed ports, as defined in the 'curlsecurityallowedport' setting.
*
* @return array the array of whitelisted ports.
* @return array the array of allowed ports.
*/
protected function get_whitelisted_ports() {
protected function get_allowed_ports() {
global $CFG;
if (!isset($CFG->curlsecurityallowedport)) {
return [];
@ -272,11 +272,11 @@ class curl_security_helper extends curl_security_helper_base {
}
/**
* Helper that returns the blacklisted hosts, as defined in the 'curlsecurityblockedhosts' setting.
* Helper that returns the blocked hosts, as defined in the 'curlsecurityblockedhosts' setting.
*
* @return array the array of blacklisted host entries.
* @return array the array of blocked host entries.
*/
protected function get_blacklisted_hosts() {
protected function get_blocked_hosts() {
global $CFG;
if (!isset($CFG->curlsecurityblockedhosts)) {
return [];

View file

@ -38,7 +38,7 @@ class mustache_engine extends \Mustache_Engine {
/**
* @var string[] Names of helpers that aren't allowed to be called within other helpers.
*/
private $blacklistednestedhelpers = [];
private $disallowednestedhelpers = [];
/**
* Mustache engine constructor.
@ -47,13 +47,19 @@ class mustache_engine extends \Mustache_Engine {
* $options = [
* // A list of helpers (by name) to prevent from executing within the rendering
* // of other helpers.
* 'blacklistednestedhelpers' => ['js']
* 'disallowednestedhelpers' => ['js']
* ];
* @param array $options [description]
*/
public function __construct(array $options = []) {
if (isset($options['blacklistednestedhelpers'])) {
$this->blacklistednestedhelpers = $options['blacklistednestedhelpers'];
debugging('blacklistednestedhelpers option is deprecated. Use disallowednestedhelpers instead.', DEBUG_DEVELOPER);
$this->disallowednestedhelpers = $options['blacklistednestedhelpers'];
}
if (isset($options['disallowednestedhelpers'])) {
$this->disallowednestedhelpers = $options['disallowednestedhelpers'];
}
parent::__construct($options);
@ -69,7 +75,7 @@ class mustache_engine extends \Mustache_Engine {
public function getHelpers()
{
if (!isset($this->helpers)) {
$this->helpers = new mustache_helper_collection(null, $this->blacklistednestedhelpers);
$this->helpers = new mustache_helper_collection(null, $this->disallowednestedhelpers);
}
return $this->helpers;

View file

@ -34,7 +34,7 @@ class mustache_helper_collection extends \Mustache_HelperCollection {
/**
* @var string[] Names of helpers that aren't allowed to be called within other helpers.
*/
private $blacklistednestedhelpers = [];
private $disallowednestedhelpers = [];
/**
* Helper Collection constructor.
@ -44,43 +44,43 @@ class mustache_helper_collection extends \Mustache_HelperCollection {
* @throws \Mustache_Exception_InvalidArgumentException if the $helpers argument isn't an array or Traversable
*
* @param array|\Traversable $helpers (default: null)
* @param string[] $blacklistednestedhelpers Names of helpers that aren't allowed to be called within other helpers.
* @param string[] $disallowednestedhelpers Names of helpers that aren't allowed to be called within other helpers.
*/
public function __construct($helpers = null, array $blacklistednestedhelpers = []) {
$this->blacklistednestedhelpers = $blacklistednestedhelpers;
public function __construct($helpers = null, array $disallowednestedhelpers = []) {
$this->disallowednestedhelpers = $disallowednestedhelpers;
parent::__construct($helpers);
}
/**
* Add a helper to this collection.
*
* This function has overridden the parent implementation to provide blacklist
* This function has overridden the parent implementation to provide disallowing
* functionality for certain helpers to prevent them being called from within
* other helpers. This is because the JavaScript helper can be used in a
* security exploit if it can be nested.
*
* The function will wrap callable helpers in an anonymous function that strips
* out the blacklisted helpers from the source string before giving it to the
* helper function. This prevents the blacklisted helper functions from being
* out the disallowed helpers from the source string before giving it to the
* helper function. This prevents the disallowed helper functions from being
* called by nested render functions from within other helpers.
*
* @see \Mustache_HelperCollection::add()
* @param string $name
* @param mixed $helper
*/
public function add($name, $helper)
{
$blacklist = $this->blacklistednestedhelpers;
public function add($name, $helper) {
if (is_callable($helper) && !empty($blacklist)) {
$helper = function($source, \Mustache_LambdaHelper $lambdahelper) use ($helper, $blacklist) {
$disallowedlist = $this->disallowednestedhelpers;
// Temporarily override the blacklisted helpers to return nothing
if (is_callable($helper) && !empty($disallowedlist)) {
$helper = function($source, \Mustache_LambdaHelper $lambdahelper) use ($helper, $disallowedlist) {
// Temporarily override the disallowed helpers to return nothing
// so that they can't be executed from within other helpers.
$disabledhelpers = $this->disable_helpers($blacklist);
$disabledhelpers = $this->disable_helpers($disallowedlist);
// Call the original function with the modified sources.
$result = call_user_func($helper, $source, $lambdahelper);
// Restore the original blacklisted helper implementations now
// Restore the original disallowed helper implementations now
// that this helper has finished executing so that the rest of
// the rendering process continues to work correctly.
$this->restore_helpers($disabledhelpers);
@ -89,7 +89,7 @@ class mustache_helper_collection extends \Mustache_HelperCollection {
// This is done because a secondary render is called on the result
// of a helper function if it still includes mustache tags. See
// the section function of Mustache_Compiler for details.
return $this->strip_blacklisted_helpers($blacklist, $result);
return $this->strip_disallowed_helpers($disallowedlist, $result);
};
}
@ -137,18 +137,18 @@ class mustache_helper_collection extends \Mustache_HelperCollection {
}
/**
* Parse the given string and remove any reference to blacklisted helpers.
* Parse the given string and remove any reference to disallowed helpers.
*
* E.g.
* $blacklist = ['js'];
* $disallowedlist = ['js'];
* $string = "core, move, {{#js}} some nasty JS hack {{/js}}"
* result: "core, move, {{}}"
*
* @param string[] $blacklist List of helper names to strip
* @param string[] $disallowedlist List of helper names to strip
* @param string $string String to parse
* @return string Parsed string
*/
public function strip_blacklisted_helpers($blacklist, $string) {
public function strip_disallowed_helpers($disallowedlist, $string) {
$starttoken = \Mustache_Tokenizer::T_SECTION;
$endtoken = \Mustache_Tokenizer::T_END_SECTION;
if ($endtoken == '/') {
@ -160,7 +160,7 @@ class mustache_helper_collection extends \Mustache_HelperCollection {
// the user is able to change the delimeters on a per template
// basis so they may not be curly braces.
return '/\s*' . $starttoken . '\s*'. $name . '\W+.*' . $endtoken . '\s*' . $name . '\s*/';
}, $blacklist);
}, $disallowedlist);
// This will strip out unwanted helpers from the $source string
// before providing it to the original helper function.
@ -168,9 +168,25 @@ class mustache_helper_collection extends \Mustache_HelperCollection {
// Before:
// "core, move, {{#js}} some nasty JS hack {{/js}}"
// After:
// "core, move, {{}}"
// "core, move, {{}}".
return preg_replace_callback($regexes, function() {
return '';
}, $string);
}
/**
* Parse the given string and remove any reference to disallowed helpers.
*
* @deprecated Deprecated since Moodle 3.10 (MDL-69050) - use {@see self::strip_disallowed_helpers()}
* @param string[] $disallowedlist List of helper names to strip
* @param string $string String to parse
* @return string Parsed string
*/
public function strip_blacklisted_helpers($disallowedlist, $string) {
debugging('mustache_helper_collection::strip_blacklisted_helpers() is deprecated. ' .
'Please use mustache_helper_collection::strip_disallowed_helpers() instead.', DEBUG_DEVELOPER);
return $this->strip_disallowed_helpers($disallowedlist, $string);
}
}

View file

@ -49,7 +49,7 @@ function events_trigger() {
/**
* List all core subsystems and their location
*
* This is a whitelist of components that are part of the core and their
* This is a list of components that are part of the core and their
* language strings are defined in /lang/en/<<subsystem>>.php. If a given
* plugin is not listed here and it does not have proper plugintype prefix,
* then it is considered as course activity module.

View file

@ -1158,7 +1158,6 @@ function enrol_selfenrol_available($courseid) {
continue;
}
if ($instance->enrol === 'guest') {
// blacklist known temporary guest plugins
continue;
}
if ($plugins[$instance->enrol]->show_enrolme_link($instance)) {

View file

@ -1105,7 +1105,7 @@ function external_generate_token_for_current_user($service) {
$unsettoken = true;
}
// Remove token if its ip not in whitelist.
// Remove token if its IP is restricted.
if (isset($token->iprestriction) and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
$unsettoken = true;
}

View file

@ -3018,7 +3018,7 @@ class curl {
private $cookie = false;
/** @var bool tracks multiple headers in response - redirect detection */
private $responsefinished = false;
/** @var security helper class, responsible for checking host/ports against blacklist/whitelist entries.*/
/** @var security helper class, responsible for checking host/ports against allowed/blocked entries.*/
private $securityhelper;
/** @var bool ignoresecurity a flag which can be supplied to the constructor, allowing security to be bypassed. */
private $ignoresecurity;
@ -3571,7 +3571,7 @@ class curl {
* @return bool
*/
protected function request($url, $options = array()) {
// Reset here so that the data is valid when result returned from cache, or if we return due to a blacklist hit.
// Reset here so that the data is valid when result returned from cache, or if we return due to a blocked URL hit.
$this->reset_request_state_vars();
if ((defined('PHPUNIT_TEST') && PHPUNIT_TEST)) {
@ -3581,8 +3581,8 @@ class curl {
}
}
// If curl security is enabled, check the URL against the blacklist before calling curl_exec.
// Note: This will only check the base url. In the case of redirects, the blacklist is also after the curl_exec.
// If curl security is enabled, check the URL against the list of blocked URLs before calling curl_exec.
// Note: This will only check the base url. In the case of redirects, the blocking check is also after the curl_exec.
if (!$this->ignoresecurity && $this->securityhelper->url_is_blocked($url)) {
$this->error = $this->securityhelper->get_blocked_url_string();
return $this->error;
@ -3605,7 +3605,7 @@ class curl {
$this->errno = curl_errno($curl);
// Note: $this->response and $this->rawresponse are filled by $hits->formatHeader callback.
// In the case of redirects (which curl blindly follows), check the post-redirect URL against the blacklist entries too.
// In the case of redirects (which curl blindly follows), check the post-redirect URL against the list of blocked list too.
if (intval($this->info['redirect_count']) > 0 && !$this->ignoresecurity
&& $this->securityhelper->url_is_blocked($this->info['url'])) {
$this->reset_request_state_vars();

View file

@ -285,7 +285,7 @@ class filetypes_util {
$types = [];
foreach ($groupinfo->extensions as $extension) {
if ($onlytypes && !$this->is_whitelisted($extension, $onlytypes)) {
if ($onlytypes && !$this->is_listed($extension, $onlytypes)) {
$group->selectable = false;
$group->expanded = true;
$group->ext = '';
@ -328,7 +328,7 @@ class filetypes_util {
continue;
}
$extension = '.'.$extension;
if ($onlytypes && !$this->is_whitelisted($extension, $onlytypes)) {
if ($onlytypes && !$this->is_listed($extension, $onlytypes)) {
continue;
}
if (!isset($info['groups']) || empty($info['groups'])) {
@ -416,35 +416,53 @@ class filetypes_util {
}
/**
* Should the given file type be considered as a part of the given whitelist.
* Should the file type be considered as a part of the given list.
*
* If multiple types are provided, all of them must be part of the
* whitelist. Empty type is part of any whitelist. Any type is part of an
* empty whitelist.
* If multiple types are provided, all of them must be part of the list. Empty type is part of any list.
* Any type is part of an empty list.
*
* @param string|array $types File types to be checked
* @param string|array $whitelist An array or string of whitelisted types
* @param string|array $types File type or list of types to be checked.
* @param string|array $list An array or string listing the types to check against.
* @return boolean
*/
public function is_whitelisted($types, $whitelist) {
return empty($this->get_not_whitelisted($types, $whitelist));
public function is_listed($types, $list) {
return empty($this->get_not_listed($types, $list));
}
/**
* Returns all types that are not part of the give whitelist.
* Should the given file type be considered as a part of the given list.
*
* This is similar check to the {@link self::is_whitelisted()} but this one
* actually returns the extra types.
* If multiple types are provided, all of them must be part of the
* list. Empty type is part of any list. Any type is part of an
* empty list.
*
* @param string|array $types File types to be checked
* @param string|array $whitelist An array or string of whitelisted types
* @return array Types not present in the whitelist
* @deprecated since Moodle 3.10 MDL-69050 - please use {@see self::is_listed()} instead.
* @param string|array $types File type or list of types to be checked.
* @param string|array $list An array or string listing the types to check against.
* @return boolean
*/
public function get_not_whitelisted($types, $whitelist) {
public function is_whitelisted($types, $list) {
$whitelistedtypes = $this->expand($whitelist, true, true);
debugging('filetypes_util::is_whitelisted() is deprecated. Please use filetypes_util::is_listed() instead.',
DEBUG_DEVELOPER);
if (empty($whitelistedtypes) || $whitelistedtypes == ['*']) {
return $this->is_listed($types, $list);
}
/**
* Returns all types that are not part of the given list.
*
* This is similar check to the {@see self::is_listed()} but this one actually returns the extra types.
*
* @param string|array $types File type or list of types to be checked.
* @param string|array $list An array or string listing the types to check against.
* @return array Types not present in the list.
*/
public function get_not_listed($types, $list) {
$listedtypes = $this->expand($list, true, true);
if (empty($listedtypes) || $listedtypes == ['*']) {
return [];
}
@ -454,22 +472,40 @@ class filetypes_util {
return [];
}
return array_diff($giventypes, $whitelistedtypes);
return array_diff($giventypes, $listedtypes);
}
/**
* Returns all types that are not part of the given list.
*
* This is similar check to the {@see self::is_listed()} but this one actually returns the extra types.
*
* @deprecated since Moodle 3.10 MDL-69050 - please use {@see self::get_not_whitelisted()} instead.
* @param string|array $types File type or list of types to be checked.
* @param string|array $list An array or string listing the types to check against.
* @return array Types not present in the list.
*/
public function get_not_whitelisted($types, $list) {
debugging('filetypes_util::get_not_whitelisted() is deprecated. Please use filetypes_util::get_not_listed() instead.',
DEBUG_DEVELOPER);
return $this->get_not_listed($types, $list);
}
/**
* Is the given filename of an allowed file type?
*
* Empty whitelist is interpretted as "any file type is allowed" rather
* Empty allowlist is interpreted as "any file type is allowed" rather
* than "no file can be uploaded".
*
* @param string $filename the file name
* @param string|array $whitelist list of allowed file extensions
* @param string|array $allowlist list of allowed file extensions
* @return boolean True if the file type is allowed, false if not
*/
public function is_allowed_file_type($filename, $whitelist) {
public function is_allowed_file_type($filename, $allowlist) {
$allowedextensions = $this->expand($whitelist);
$allowedextensions = $this->expand($allowlist);
if (empty($allowedextensions) || $allowedextensions == ['*']) {
return true;

View file

@ -328,9 +328,9 @@ class MoodleQuickForm_filemanager extends HTML_QuickForm_element implements temp
}
$filetypesutil = new \core_form\filetypes_util();
$whitelist = $filetypesutil->normalize_file_types($this->_options['accepted_types']);
$allowlist = $filetypesutil->normalize_file_types($this->_options['accepted_types']);
if (empty($whitelist) || $whitelist === ['*']) {
if (empty($allowlist) || $allowlist === ['*']) {
// Any file type is allowed, nothing to check here.
return;
}
@ -344,14 +344,14 @@ class MoodleQuickForm_filemanager extends HTML_QuickForm_element implements temp
}
foreach ($draftfiles as $file) {
if (!$filetypesutil->is_allowed_file_type($file->filename, $whitelist)) {
if (!$filetypesutil->is_allowed_file_type($file->filename, $allowlist)) {
$wrongfiles[] = $file->filename;
}
}
if ($wrongfiles) {
$a = array(
'whitelist' => implode(', ', $whitelist),
'allowlist' => implode(', ', $allowlist),
'wrongfiles' => implode(', ', $wrongfiles),
);
return get_string('err_wrongfileextension', 'core_form', $a);

View file

@ -248,9 +248,9 @@ class MoodleQuickForm_filepicker extends HTML_QuickForm_input implements templat
public function validateSubmitValue($value) {
$filetypesutil = new \core_form\filetypes_util();
$whitelist = $filetypesutil->normalize_file_types($this->_options['accepted_types']);
$allowlist = $filetypesutil->normalize_file_types($this->_options['accepted_types']);
if (empty($whitelist) || $whitelist === ['*']) {
if (empty($allowlist) || $allowlist === ['*']) {
// Any file type is allowed, nothing to check here.
return;
}
@ -264,14 +264,14 @@ class MoodleQuickForm_filepicker extends HTML_QuickForm_input implements templat
}
foreach ($draftfiles->list as $file) {
if (!$filetypesutil->is_allowed_file_type($file->filename, $whitelist)) {
if (!$filetypesutil->is_allowed_file_type($file->filename, $allowlist)) {
$wrongfiles[] = $file->filename;
}
}
if ($wrongfiles) {
$a = array(
'whitelist' => implode(', ', $whitelist),
'allowlist' => implode(', ', $allowlist),
'wrongfiles' => implode(', ', $wrongfiles),
);
return get_string('err_wrongfileextension', 'core_form', $a);

View file

@ -242,10 +242,10 @@ class MoodleQuickForm_filetypes extends MoodleQuickForm_group {
if ($this->onlytypes) {
// Assert that all file types are allowed here.
$notwhitelisted = $this->util->get_not_whitelisted($value['filetypes'], $this->onlytypes);
$notlisted = $this->util->get_not_listed($value['filetypes'], $this->onlytypes);
if ($notwhitelisted) {
return get_string('filetypesnotwhitelisted', 'core_form', implode(', ', $notwhitelisted));
if ($notlisted) {
return get_string('filetypesnotallowed', 'core_form', implode(', ', $notlisted));
}
}

View file

@ -207,67 +207,67 @@ class filetypes_util_testcase extends advanced_testcase {
/**
* Test checking that a type is among others.
*/
public function test_is_whitelisted() {
public function test_is_listed() {
$this->resetAfterTest(true);
$util = new filetypes_util();
// These should be intuitively true.
$this->assertTrue($util->is_whitelisted('txt', 'text/plain'));
$this->assertTrue($util->is_whitelisted('txt', 'doc txt rtf'));
$this->assertTrue($util->is_whitelisted('.txt', '.doc;.txt;.rtf'));
$this->assertTrue($util->is_whitelisted('audio', 'text/plain audio video'));
$this->assertTrue($util->is_whitelisted('text/plain', 'text/plain audio video'));
$this->assertTrue($util->is_whitelisted('jpg jpe jpeg', 'image/jpeg'));
$this->assertTrue($util->is_whitelisted(['jpg', 'jpe', '.png'], 'image'));
$this->assertTrue($util->is_listed('txt', 'text/plain'));
$this->assertTrue($util->is_listed('txt', 'doc txt rtf'));
$this->assertTrue($util->is_listed('.txt', '.doc;.txt;.rtf'));
$this->assertTrue($util->is_listed('audio', 'text/plain audio video'));
$this->assertTrue($util->is_listed('text/plain', 'text/plain audio video'));
$this->assertTrue($util->is_listed('jpg jpe jpeg', 'image/jpeg'));
$this->assertTrue($util->is_listed(['jpg', 'jpe', '.png'], 'image'));
// These should be intuitively false.
$this->assertFalse($util->is_whitelisted('.gif', 'text/plain'));
$this->assertFalse($util->is_listed('.gif', 'text/plain'));
// Not all text/plain formats are in the document group.
$this->assertFalse($util->is_whitelisted('text/plain', 'document'));
$this->assertFalse($util->is_listed('text/plain', 'document'));
// Not all documents (and also the group itself) is not a plain text.
$this->assertFalse($util->is_whitelisted('document', 'text/plain'));
$this->assertFalse($util->is_listed('document', 'text/plain'));
// This may look wrong at the first sight as you might expect that the
// mimetype should simply map to an extension ...
$this->assertFalse($util->is_whitelisted('image/jpeg', '.jpg'));
$this->assertFalse($util->is_listed('image/jpeg', '.jpg'));
// But it is principally same situation as this (there is no 1:1 mapping).
$this->assertFalse($util->is_whitelisted('.c', '.txt'));
$this->assertTrue($util->is_whitelisted('.txt .c', 'text/plain'));
$this->assertFalse($util->is_whitelisted('text/plain', '.c'));
$this->assertFalse($util->is_listed('.c', '.txt'));
$this->assertTrue($util->is_listed('.txt .c', 'text/plain'));
$this->assertFalse($util->is_listed('text/plain', '.c'));
// Any type is included if the filter is empty.
$this->assertTrue($util->is_whitelisted('txt', ''));
$this->assertTrue($util->is_whitelisted('txt', '*'));
$this->assertTrue($util->is_listed('txt', ''));
$this->assertTrue($util->is_listed('txt', '*'));
// Empty value is part of any whitelist.
$this->assertTrue($util->is_whitelisted('', '.txt'));
// Empty value is part of any list.
$this->assertTrue($util->is_listed('', '.txt'));
}
/**
* Test getting types not present in a whitelist.
* Test getting types not present in a list.
*/
public function test_get_not_whitelisted() {
public function test_get_not_listed() {
$this->resetAfterTest(true);
$util = new filetypes_util();
$this->assertEmpty($util->get_not_whitelisted('txt', 'text/plain'));
$this->assertEmpty($util->get_not_whitelisted('txt', '.doc .txt .rtf'));
$this->assertEmpty($util->get_not_whitelisted('txt', 'text/plain'));
$this->assertEmpty($util->get_not_whitelisted(['jpg', 'jpe', 'jpeg'], 'image/jpeg'));
$this->assertEmpty($util->get_not_whitelisted('', 'foo/bar'));
$this->assertEmpty($util->get_not_whitelisted('.foobar', ''));
$this->assertEmpty($util->get_not_whitelisted('.foobar', '*'));
$this->assertEmpty($util->get_not_listed('txt', 'text/plain'));
$this->assertEmpty($util->get_not_listed('txt', '.doc .txt .rtf'));
$this->assertEmpty($util->get_not_listed('txt', 'text/plain'));
$this->assertEmpty($util->get_not_listed(['jpg', 'jpe', 'jpeg'], 'image/jpeg'));
$this->assertEmpty($util->get_not_listed('', 'foo/bar'));
$this->assertEmpty($util->get_not_listed('.foobar', ''));
$this->assertEmpty($util->get_not_listed('.foobar', '*'));
// Returned list is normalized so extensions have the dot added.
$this->assertContains('.exe', $util->get_not_whitelisted('exe', '.c .h'));
$this->assertContains('.exe', $util->get_not_listed('exe', '.c .h'));
// If this looks wrong to you, see {@link test_is_whitelisted()} for more details on this behaviour.
$this->assertContains('image/jpeg', $util->get_not_whitelisted('image/jpeg', '.jpg .jpeg'));
// If this looks wrong to you, see {@see self::test_is_listed()} for more details on this behaviour.
$this->assertContains('image/jpeg', $util->get_not_listed('image/jpeg', '.jpg .jpeg'));
}
/**
@ -361,44 +361,44 @@ class filetypes_util_testcase extends advanced_testcase {
*/
public function is_allowed_file_type_provider() {
return [
'Filetype not in extension whitelist' => [
'Filetype not in extension list' => [
'filename' => 'test.xml',
'whitelist' => '.png .jpg',
'list' => '.png .jpg',
'expected' => false
],
'Filetype not in mimetype whitelist' => [
'Filetype not in mimetype list' => [
'filename' => 'test.xml',
'whitelist' => 'image/png',
'list' => 'image/png',
'expected' => false
],
'Filetype not in group whitelist' => [
'Filetype not in group list' => [
'filename' => 'test.xml',
'whitelist' => 'web_file',
'list' => 'web_file',
'expected' => false
],
'Filetype in whitelist as extension' => [
'Filetype in list as extension' => [
'filename' => 'test.xml',
'whitelist' => 'xml',
'list' => 'xml',
'expected' => true
],
'Empty whitelist should allow all' => [
'Empty list should allow all' => [
'filename' => 'test.xml',
'whitelist' => '',
'list' => '',
'expected' => true
],
'Filetype in whitelist but later on' => [
'Filetype in list but later on' => [
'filename' => 'test.xml',
'whitelist' => 'gif;jpeg,image/png xml xlsx',
'list' => 'gif;jpeg,image/png xml xlsx',
'expected' => true
],
'Filetype in whitelist as mimetype' => [
'Filetype in list as mimetype' => [
'filename' => 'test.xml',
'whitelist' => 'image/png application/xml',
'list' => 'image/png application/xml',
'expected' => true
],
'Filetype in whitelist as group' => [
'Filetype in list as group' => [
'filename' => 'test.html',
'whitelist' => 'video,web_file',
'list' => 'video,web_file',
'expected' => true
],
];
@ -408,12 +408,12 @@ class filetypes_util_testcase extends advanced_testcase {
* Test is_allowed_file_type().
* @dataProvider is_allowed_file_type_provider
* @param string $filename The filename to check
* @param string $whitelist The space , or ; separated list of types supported
* @param string $list The space , or ; separated list of types supported
* @param boolean $expected The expected result. True if the file is allowed, false if not.
*/
public function test_is_allowed_file_type($filename, $whitelist, $expected) {
public function test_is_allowed_file_type($filename, $list, $expected) {
$util = new filetypes_util();
$this->assertSame($expected, $util->is_allowed_file_type($filename, $whitelist));
$this->assertSame($expected, $util->is_allowed_file_type($filename, $list));
}
/**
@ -484,4 +484,26 @@ class filetypes_util_testcase extends advanced_testcase {
$util = new filetypes_util();
$this->assertSame($expected, $util->get_unknown_file_types($filetypes));
}
/**
* Test that a debugging noticed is displayed when calling is_whitelisted().
*/
public function test_deprecation_is_whitelisted() {
$util = new filetypes_util();
$this->assertTrue($util->is_whitelisted('txt', 'text/plain'));
$this->assertDebuggingCalled('filetypes_util::is_whitelisted() is deprecated. ' .
'Please use filetypes_util::is_listed() instead.', DEBUG_DEVELOPER);
}
/**
* Test that a debugging noticed is displayed when calling get_not_whitelisted().
*/
public function test_deprecation_get_not_whitelisted() {
$util = new filetypes_util();
$this->assertEmpty($util->get_not_whitelisted('txt', 'text/plain'));
$this->assertDebuggingCalled('filetypes_util::get_not_whitelisted() is deprecated. ' .
'Please use filetypes_util::get_not_listed() instead.', DEBUG_DEVELOPER);
}
}

View file

@ -129,7 +129,7 @@ class renderer_base {
// Don't allow the JavaScript helper to be executed from within another
// helper. If it's allowed it can be used by users to inject malicious
// JS into the page.
'blacklistednestedhelpers' => ['js']));
'disallowednestedhelpers' => ['js']));
}

View file

@ -78,7 +78,7 @@ class core_curl_security_helper_testcase extends advanced_testcase {
];
// Format: url, blocked hosts, allowed ports, expected result.
return [
// Base set without the blacklist enabled - no checking takes place.
// Base set without the blocklist enabled - no checking takes place.
[$simpledns, "http://localhost/x.png", "", "", false], // IP=127.0.0.1, Port=80 (port inferred from http).
[$simpledns, "http://localhost:80/x.png", "", "", false], // IP=127.0.0.1, Port=80 (specific port overrides http scheme).
[$simpledns, "https://localhost/x.png", "", "", false], // IP=127.0.0.1, Port=443 (port inferred from https).
@ -136,7 +136,7 @@ class core_curl_security_helper_testcase extends advanced_testcase {
// Test using multiple A records.
// Multiple record DNS gives two IPs for the same host, we want to make
// sure that if we blacklist one of those (doesn't matter which one)
// sure that if we block one of those (doesn't matter which one)
// the request is blocked.
[$multiplerecorddns, "http://sub.example.com", '1.2.3.4', "", true],
[$multiplerecorddns, "http://sub.example.com", '5.6.7.8', "", true],
@ -284,8 +284,8 @@ class core_curl_security_helper_testcase extends advanced_testcase {
["80", "80\n443", false],
[80, "80\n443", false],
[443, "80\n443", false],
[0, "", true], // Port 0 and below are always invalid, even when the admin hasn't set whitelist entries.
[-1, "", true], // Port 0 and below are always invalid, even when the admin hasn't set whitelist entries.
[0, "", true], // Port 0 and below are always invalid, even when the admin hasn't set allowed entries.
[-1, "", true], // Port 0 and below are always invalid, even when the admin hasn't set allowed entries.
[null, "", true], // Non-string, non-int values are invalid.
];
}

View file

@ -30,94 +30,94 @@ use core\output\mustache_helper_collection;
*/
class core_output_mustache_helper_collection_testcase extends advanced_testcase {
/**
* Test cases to confirm that blacklisted helpers are stripped from the source
* Test cases to confirm that disallowed helpers are stripped from the source
* text by the helper before being passed to other another helper. This prevents
* nested calls to helpers.
*/
public function get_strip_blacklisted_helpers_testcases() {
public function get_strip_disallowed_helpers_testcases() {
return [
'no blacklist' => [
'blacklist' => [],
'no disallowed' => [
'disallowed' => [],
'input' => 'core, move, {{#js}} some nasty JS {{/js}}',
'expected' => 'core, move, {{#js}} some nasty JS {{/js}}'
],
'blacklist no match' => [
'blacklist' => ['foo'],
'disallowed no match' => [
'disallowed' => ['foo'],
'input' => 'core, move, {{#js}} some nasty JS {{/js}}',
'expected' => 'core, move, {{#js}} some nasty JS {{/js}}'
],
'blacklist partial match 1' => [
'blacklist' => ['js'],
'disallowed partial match 1' => [
'disallowed' => ['js'],
'input' => 'core, move, {{#json}} some nasty JS {{/json}}',
'expected' => 'core, move, {{#json}} some nasty JS {{/json}}'
],
'blacklist partial match 2' => [
'blacklist' => ['js'],
'disallowed partial match 2' => [
'disallowed' => ['js'],
'input' => 'core, move, {{#onjs}} some nasty JS {{/onjs}}',
'expected' => 'core, move, {{#onjs}} some nasty JS {{/onjs}}'
],
'single blacklist 1' => [
'blacklist' => ['js'],
'single disallowed 1' => [
'disallowed' => ['js'],
'input' => 'core, move, {{#js}} some nasty JS {{/js}}',
'expected' => 'core, move, {{}}'
],
'single blacklist 2' => [
'blacklist' => ['js'],
'single disallowed 2' => [
'disallowed' => ['js'],
'input' => 'core, move, {{ # js }} some nasty JS {{ / js }}',
'expected' => 'core, move, {{}}'
],
'single blacklist 3' => [
'blacklist' => ['js'],
'single disallowed 3' => [
'disallowed' => ['js'],
'input' => 'core, {{#js}} some nasty JS {{/js}}, test',
'expected' => 'core, {{}}, test'
],
'single blacklist 3' => [
'blacklist' => ['js'],
'single disallowed 3' => [
'disallowed' => ['js'],
'input' => 'core, {{#ok}} this is ok {{/ok}}, {{#js}} some nasty JS {{/js}}',
'expected' => 'core, {{#ok}} this is ok {{/ok}}, {{}}'
],
'single blacklist multiple matches 1' => [
'blacklist' => ['js'],
'single disallowed multiple matches 1' => [
'disallowed' => ['js'],
'input' => 'core, {{#js}} some nasty JS {{/js}}, {{#js}} some nasty JS {{/js}}',
'expected' => 'core, {{}}'
],
'single blacklist multiple matches 2' => [
'blacklist' => ['js'],
'single disallowed multiple matches 2' => [
'disallowed' => ['js'],
'input' => 'core, {{ # js }} some nasty JS {{ / js }}, {{ # js }} some nasty JS {{ / js }}',
'expected' => 'core, {{}}'
],
'single blacklist multiple matches nested 1' => [
'blacklist' => ['js'],
'single disallowed multiple matches nested 1' => [
'disallowed' => ['js'],
'input' => 'core, move, {{#js}} some nasty JS {{#js}} some nasty JS {{/js}} {{/js}}',
'expected' => 'core, move, {{}}'
],
'single blacklist multiple matches nested 2' => [
'blacklist' => ['js'],
'single disallowed multiple matches nested 2' => [
'disallowed' => ['js'],
'input' => 'core, move, {{ # js }} some nasty JS {{ # js }} some nasty JS {{ / js }}{{ / js }}',
'expected' => 'core, move, {{}}'
],
'multiple blacklist 1' => [
'blacklist' => ['js', 'foo'],
'multiple disallowed 1' => [
'disallowed' => ['js', 'foo'],
'input' => 'core, move, {{#js}} some nasty JS {{/js}}',
'expected' => 'core, move, {{}}'
],
'multiple blacklist 2' => [
'blacklist' => ['js', 'foo'],
'multiple disallowed 2' => [
'disallowed' => ['js', 'foo'],
'input' => 'core, {{#foo}} blah {{/foo}}, {{#js}} js {{/js}}',
'expected' => 'core, {{}}, {{}}'
],
'multiple blacklist 3' => [
'blacklist' => ['js', 'foo'],
'multiple disallowed 3' => [
'disallowed' => ['js', 'foo'],
'input' => '{{#foo}} blah {{/foo}}, {{#foo}} blah {{/foo}}, {{#js}} js {{/js}}',
'expected' => '{{}}, {{}}'
],
'multiple blacklist 4' => [
'blacklist' => ['js', 'foo'],
'multiple disallowed 4' => [
'disallowed' => ['js', 'foo'],
'input' => '{{#foo}} blah {{/foo}}, {{#js}} js {{/js}}, {{#foo}} blah {{/foo}}',
'expected' => '{{}}'
],
'multiple blacklist 4' => [
'blacklist' => ['js', 'foo'],
'multiple disallowed 4' => [
'disallowed' => ['js', 'foo'],
'input' => 'core, move, {{#js}} JS {{#foo}} blah {{/foo}} {{/js}}',
'expected' => 'core, move, {{}}'
],
@ -126,29 +126,29 @@ class core_output_mustache_helper_collection_testcase extends advanced_testcase
/**
* Test that the mustache_helper_collection class correctly strips
* @dataProvider get_strip_blacklisted_helpers_testcases()
* @param string[] $blacklist The list of helpers to strip
* @dataProvider get_strip_disallowed_helpers_testcases()
* @param string[] $disallowed The list of helpers to strip
* @param string $input The input string for the helper
* @param string $expected The expected output of the string after blacklist strip
* @param string $expected The expected output of the string after disallowed strip
*/
public function test_strip_blacklisted_helpers($blacklist, $input, $expected) {
$collection = new mustache_helper_collection(null, $blacklist);
$this->assertEquals($expected, $collection->strip_blacklisted_helpers($blacklist, $input));
public function test_strip_disallowed_helpers($disallowed, $input, $expected) {
$collection = new mustache_helper_collection(null, $disallowed);
$this->assertEquals($expected, $collection->strip_disallowed_helpers($disallowed, $input));
}
/**
* Test that the blacklisted helpers are disabled during the execution of other
* Test that the disallowed helpers are disabled during the execution of other
* helpers.
*
* Any non-blacklisted helper should still be available to call during the
* Any allowed helper should still be available to call during the
* execution of a helper.
*/
public function test_blacklisted_helpers_disabled_during_execution() {
public function test_disallowed_helpers_disabled_during_execution() {
$engine = new \Mustache_Engine();
$context = new \Mustache_Context();
$lambdahelper = new \Mustache_LambdaHelper($engine, $context);
$blacklist = ['bad'];
$collection = new mustache_helper_collection(null, $blacklist);
$disallowed = ['bad'];
$collection = new mustache_helper_collection(null, $disallowed);
$badcalled = false;
$goodcalled = false;
@ -174,4 +174,16 @@ class core_output_mustache_helper_collection_testcase extends advanced_testcase
$this->assertTrue($goodcalled);
$this->assertFalse($badcalled);
}
/**
* Test that calling deprecated method strip_blacklisted_helpers() still works and shows developer debugging.
*/
public function test_deprecated_strip_blacklisted_helpers() {
$collection = new mustache_helper_collection(null, ['js']);
$stripped = $collection->strip_blacklisted_helpers(['js'], '{{#js}} JS {{/js}}');
$this->assertEquals('{{}}', $stripped);
$this->assertDebuggingCalled('mustache_helper_collection::strip_blacklisted_helpers() is deprecated. ' .
'Please use mustache_helper_collection::strip_disallowed_helpers() instead.', DEBUG_DEVELOPER);
}
}

View file

@ -48,6 +48,10 @@ information provided here is intended especially for developers.
* The ZipStream-PHP library has been added to Moodle core in /lib/zipstream.
* The php-enum library has been added to Moodle core in /lib/php-enum.
* The http-message library has been added to Moodle core in /lib/http-message.
* Methods `filetypes_util::is_whitelisted()` and `filetypes_util::get_not_whitelisted()` have been deprecated and
renamed to `is_listed()` and `get_not_listed()` respectively.
* Method `mustache_helper_collection::strip_blacklisted_helpers()` has been deprecated and renamed to
`strip_disallowed_helpers()`.
=== 3.9 ===
* Following function has been deprecated, please use \core\task\manager::run_from_cli().

View file

@ -52,16 +52,16 @@ EXCEPTION = function(c) {
config.width = config.width || (M.cfg.developerdebug) ? Math.floor(Y.one(document.body).get('winWidth') / 3) + 'px' : null;
config.closeButton = true;
// We need to whitelist some properties which are part of the exception
// We need to allow some properties which are part of the exception
// prototype, otherwise AttributeCore filters them during value normalisation.
var whitelist = [
var allowlist = [
'message',
'name',
'fileName',
'lineNumber',
'stack'
];
Y.Array.each(whitelist, function(k) {
Y.Array.each(allowlist, function(k) {
config[k] = c[k];
});

View file

@ -52,16 +52,16 @@ EXCEPTION = function(c) {
config.width = config.width || (M.cfg.developerdebug) ? Math.floor(Y.one(document.body).get('winWidth') / 3) + 'px' : null;
config.closeButton = true;
// We need to whitelist some properties which are part of the exception
// We need to allow some properties which are part of the exception
// prototype, otherwise AttributeCore filters them during value normalisation.
var whitelist = [
var allowlist = [
'message',
'name',
'fileName',
'lineNumber',
'stack'
];
Y.Array.each(whitelist, function(k) {
Y.Array.each(allowlist, function(k) {
config[k] = c[k];
});

View file

@ -22,16 +22,16 @@ EXCEPTION = function(c) {
config.width = config.width || (M.cfg.developerdebug) ? Math.floor(Y.one(document.body).get('winWidth') / 3) + 'px' : null;
config.closeButton = true;
// We need to whitelist some properties which are part of the exception
// We need to allow some properties which are part of the exception
// prototype, otherwise AttributeCore filters them during value normalisation.
var whitelist = [
var allowlist = [
'message',
'name',
'fileName',
'lineNumber',
'stack'
];
Y.Array.each(whitelist, function(k) {
Y.Array.each(allowlist, function(k) {
config[k] = c[k];
});

View file

@ -729,7 +729,7 @@ function core_message_can_edit_message_profile($user) {
}
/**
* Implements callback user_preferences, whitelists preferences that users are allowed to update directly
* Implements callback user_preferences, lists preferences that users are allowed to update directly
*
* Used in {@see core_user::fill_preferences_cache()}, see also {@see useredit_update_user_preference()}
*

View file

@ -257,7 +257,7 @@ function mnet_server_dispatch($payload) {
// $method is something like: "mod/forum/lib.php/forum_add_instance"
// $params is an array of parameters. A parameter might itself be an array.
// Whitelist characters that are permitted in a method name
// Check that the method name consists of allowed characters only.
// The method name must not begin with a / - avoid absolute paths
// A dot character . is only allowed in the filename, i.e. something.php
if (0 == preg_match("@^[A-Za-z0-9]+/[A-Za-z0-9/_\.-]+(\.php/)?[A-Za-z0-9_-]+$@",$method)) {

View file

@ -499,54 +499,54 @@ class workshop {
/**
* Check given file types and return invalid/unknown ones.
*
* Empty whitelist is interpretted as "any extension is valid".
* Empty allowlist is interpretted as "any extension is valid".
*
* @deprecated since Moodle 3.4 MDL-56486 - please use the {@link core_form\filetypes_util}
* @param string|array $extensions list of file extensions
* @param string|array $whitelist list of valid extensions
* @return array list of invalid extensions not found in the whitelist
* @param string|array $allowlist list of valid extensions
* @return array list of invalid extensions not found in the allowlist
*/
public static function invalid_file_extensions($extensions, $whitelist) {
public static function invalid_file_extensions($extensions, $allowlist) {
debugging('The method workshop::invalid_file_extensions() is deprecated.
Please use the methods provided by the \core_form\filetypes_util class.', DEBUG_DEVELOPER);
$extensions = self::normalize_file_extensions($extensions);
$whitelist = self::normalize_file_extensions($whitelist);
$allowlist = self::normalize_file_extensions($allowlist);
if (empty($extensions) or empty($whitelist)) {
if (empty($extensions) or empty($allowlist)) {
return array();
}
// Return those items from $extensions that are not present in $whitelist.
return array_keys(array_diff_key(array_flip($extensions), array_flip($whitelist)));
// Return those items from $extensions that are not present in $allowlist.
return array_keys(array_diff_key(array_flip($extensions), array_flip($allowlist)));
}
/**
* Is the file have allowed to be uploaded to the workshop?
*
* Empty whitelist is interpretted as "any file type is allowed" rather
* Empty allowlist is interpretted as "any file type is allowed" rather
* than "no file can be uploaded".
*
* @deprecated since Moodle 3.4 MDL-56486 - please use the {@link core_form\filetypes_util}
* @param string $filename the file name
* @param string|array $whitelist list of allowed file extensions
* @param string|array $allowlist list of allowed file extensions
* @return false
*/
public static function is_allowed_file_type($filename, $whitelist) {
public static function is_allowed_file_type($filename, $allowlist) {
debugging('The method workshop::is_allowed_file_type() is deprecated.
Please use the methods provided by the \core_form\filetypes_util class.', DEBUG_DEVELOPER);
$whitelist = self::normalize_file_extensions($whitelist);
$allowlist = self::normalize_file_extensions($allowlist);
if (empty($whitelist)) {
if (empty($allowlist)) {
return true;
}
$haystack = strrev(trim(strtolower($filename)));
foreach ($whitelist as $extension) {
foreach ($allowlist as $extension) {
if (strpos($haystack, strrev($extension)) === 0) {
// The file name ends with the extension.
return true;

View file

@ -114,10 +114,10 @@ class qtype_essay_question extends question_with_responses {
if ($hasattachments) {
// Check the filetypes.
$filetypesutil = new \core_form\filetypes_util();
$whitelist = $filetypesutil->normalize_file_types($this->filetypeslist);
$allowlist = $filetypesutil->normalize_file_types($this->filetypeslist);
$wrongfiles = array();
foreach ($response['attachments']->get_files() as $file) {
if (!$filetypesutil->is_allowed_file_type($file->get_filename(), $whitelist)) {
if (!$filetypesutil->is_allowed_file_type($file->get_filename(), $allowlist)) {
$wrongfiles[] = $file->get_filename();
}
}

View file

@ -152,7 +152,7 @@ function useredit_load_preferences(&$user, $reload=true) {
* Updates the user preferences for the given user
*
* Only preference that can be updated directly will be updated here. This method is called from various WS
* updating users and should be used when updating user details. Plugins may whitelist preferences that can
* updating users and should be used when updating user details. Plugins may list preferences that can
* be updated by defining 'user_preferences' callback, {@see core_user::fill_preferences_cache()}
*
* Some parts of code may use user preference table to store internal data, in these cases it is acceptable