Skip to content

Commit

Permalink
Merge pull request #8 from backdrop/1.x
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
herbdool authored Jun 6, 2020
2 parents fa90b3a + 3e499ac commit d38dedc
Show file tree
Hide file tree
Showing 77 changed files with 1,612 additions and 357 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Backdrop aims to provide:

Requirements
------------
- PHP 5.3.2 or higher. Even if Backdrop can run on older versions of PHP, we strongly recommend that you use a [supported version of PHP](https://secure.php.net/supported-versions.php).
- PHP 5.3.2 or higher. Even if Backdrop can run on older versions of PHP, we
strongly recommend that you use a
[supported version of PHP](https://secure.php.net/supported-versions.php).
- MySQL 5.0.15 or higher with PDO enabled
- Apache (recommended) or Nginx web server
- 50 MB of disk space (recommended), 15 MB (minimum)
Expand Down Expand Up @@ -38,9 +40,10 @@ Security Issues
---------------
If you have discovered a security issue with Backdrop CMS or any of its
[contributed modules](https://github.com/backdrop-contrib/), please contact the
Backdrop Security Team directly at [[email protected]](mailto:[email protected]).
We manage security issues separately in a private repository until the issue
has been resolved. Even if you're not sure if it's a security problem, please
Backdrop Security Team directly at
[[email protected]](mailto:[email protected]).
We manage security issues separately in a private repository until the issue has
been resolved. Even if you're not sure if it's a security problem, please
contact the security team before filing an issue.

Developers
Expand Down Expand Up @@ -84,5 +87,5 @@ All Backdrop code is Copyright 2001 - 2016 by the original authors.

Backdrop also includes works under different copyright notices that are
distributed according to the terms of the GNU General Public License or a
compatible license. These individual works may have specific copyright
compatible license. These individual works may have specific copyright
information noted within their source code files or directories.
14 changes: 7 additions & 7 deletions core/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

Preamble
Preamble

The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Expand Down Expand Up @@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.

GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License applies to any program or other work which contains
Expand Down Expand Up @@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

NO WARRANTY
NO WARRANTY

11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
Expand All @@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs
How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
Expand Down
2 changes: 1 addition & 1 deletion core/includes/batch.inc
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ function _batch_finished() {

// Clean-up the session. Not needed for CLI updates.
if (isset($_SESSION)) {
unset($_SESSION['batches'][$batch['id']]);
unset($_SESSION['batches'][$_batch['id']]);
if (empty($_SESSION['batches'])) {
unset($_SESSION['batches']);
}
Expand Down
11 changes: 7 additions & 4 deletions core/includes/bootstrap.inc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* The current system version.
*/
define('BACKDROP_VERSION', '1.16.x-dev');
define('BACKDROP_VERSION', '1.17.x-dev');

/**
* Core API compatibility.
Expand Down Expand Up @@ -2014,7 +2014,7 @@ function t($string, array $args = array(), array $options = array()) {
function format_string($string, array $args = array()) {
// Transform arguments before inserting them.
foreach ($args as $key => $value) {
switch ($key[0]) {
switch (substr($key, 0, 1)) {
case '@':
// Escaped only.
$args[$key] = check_plain($value);
Expand Down Expand Up @@ -3258,7 +3258,10 @@ function _backdrop_bootstrap_sanitize_request() {
}

// If there is a query string, check its query parameters.
$destination_parts = backdrop_parse_url($_GET['destination']);
if (isset($_GET['destination'])) {
$destination_parts = backdrop_parse_url($_GET['destination']);
}

if (!empty($destination_parts['query'])) {
$sanitized_keys = _backdrop_bootstrap_sanitize_input($destination_parts['query'], $whitelist);
}
Expand Down Expand Up @@ -3289,7 +3292,7 @@ function _backdrop_bootstrap_sanitize_input(&$input, $whitelist = array()) {

if (is_array($input)) {
foreach ($input as $key => $value) {
if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
if ($key !== '' && substr($key, 0, 1) === '#' && !in_array($key, $whitelist, TRUE)) {
unset($input[$key]);
$sanitized_keys[] = $key;
}
Expand Down
26 changes: 18 additions & 8 deletions core/includes/common.inc
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ function backdrop_add_feed($url = NULL, $title = '') {
*/
function backdrop_get_feeds($delimiter = "\n") {
$feeds = backdrop_add_feed();
return implode($feeds, $delimiter);
return implode($delimiter, $feeds);
}

/**
Expand Down Expand Up @@ -834,7 +834,10 @@ function backdrop_goto($path = '', array $options = array(), $http_response_code
// We do not allow absolute URLs to be passed via $_GET, as this can be an attack vector.
if (isset($_GET['destination']) && !url_is_external($_GET['destination'])) {
$destination = backdrop_parse_url($_GET['destination']);
$path = $destination['path'];
// Double check the path derived by backdrop_parse_url() is not external.
if (!url_is_external($destination['path'])) {
$path = $destination['path'];
}
$options['query'] = $destination['query'];
$options['fragment'] = $destination['fragment'];
}
Expand Down Expand Up @@ -2398,7 +2401,9 @@ function format_date($timestamp, $date_format_name = 'medium', $pattern = '', $t
// If we have a non-custom date format use the provided date format pattern.
if ($date_format_name != 'custom') {
$date_format = system_date_format_load($date_format_name);
$pattern = isset($date_format['locales'][$langcode]) ? $date_format['locales'][$langcode] : $date_format['pattern'];
if (!empty($date_format)) {
$pattern = isset($date_format['locales'][$langcode]) ? $date_format['locales'][$langcode] : $date_format['pattern'];
}
}

// Fall back to medium if a format was not found.
Expand Down Expand Up @@ -2554,7 +2559,7 @@ function url($path = NULL, array $options = array()) {
// path is always treated as internal by default (to prevent external link
// injection vulnerabilities).
if (!isset($options['external'])) {
$options['external'] = ($path === $_GET['q']) ? FALSE : url_is_external($path);
$options['external'] = (isset($_GET['q']) && $path === $_GET['q']) ? FALSE : url_is_external($path);
}

// Preserve the original path before altering or aliasing.
Expand Down Expand Up @@ -3993,7 +3998,12 @@ function _backdrop_build_css_path($matches, $base = NULL) {
}

// Prefix with base and remove '../' segments where possible.
$path = $_base . $matches[1];
if (is_array($matches)) {
$path = $_base . $matches[1];
}
else {
$path = $_base;
}
$last = '';
while ($path != $last) {
$last = $path;
Expand Down Expand Up @@ -7184,7 +7194,7 @@ function backdrop_sort(array &$array, array $keys = array('weight'), $dir = SORT
* Checks if the key is a property.
*/
function element_property($key) {
return $key[0] == '#';
return substr($key, 0, 1) == '#';
}

/**
Expand All @@ -7198,7 +7208,7 @@ function element_properties($element) {
* Checks if the key is a child.
*/
function element_child($key) {
return !isset($key[0]) || $key[0] != '#';
return empty($key) || substr($key, 0, 1) != '#';
}

/**
Expand All @@ -7223,7 +7233,7 @@ function element_children(&$elements, $sort = FALSE) {
$children = array();
$sortable = FALSE;
foreach ($elements as $key => $value) {
if ($key === '' || $key[0] !== '#') {
if ($key === '' || substr($key, 0, 1) !== '#') {
if (is_array($value)) {
$children[$key] = $value;
if (isset($value['#weight'])) {
Expand Down
2 changes: 1 addition & 1 deletion core/includes/filetransfer/filetransfer.inc
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ abstract class FileTransfer {
$parts = explode('/', $path);
$chroot = '';
while (count($parts)) {
$check = implode($parts, '/');
$check = implode('/', $parts);
if ($this->isFile($check . '/' . backdrop_basename(__FILE__))) {
// Remove the trailing slash.
return substr($chroot, 0, -1);
Expand Down
2 changes: 1 addition & 1 deletion core/includes/install.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ function st($string, array $args = array(), array $options = array()) {

// Transform arguments before inserting them
foreach ($args as $key => $value) {
switch ($key[0]) {
switch (substr($key, 0, 1)) {
// Escaped only
case '@':
$args[$key] = check_plain($value);
Expand Down
2 changes: 1 addition & 1 deletion core/includes/pager.inc
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ function theme_pager($variables) {
global $pager_page_array, $pager_total;

// Return if there is no pager to be rendered.
if (!isset($pager_page_array[$element])) {
if (!isset($pager_page_array[$element]) || empty($pager_total)) {
return '';
}

Expand Down
4 changes: 3 additions & 1 deletion core/includes/path.inc
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@ function backdrop_match_path($path, $patterns) {
* @see request_path()
*/
function current_path() {
return $_GET['q'];
if (isset($_GET['q'])) {
return $_GET['q'];
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion core/includes/token.inc
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ function token_get_invalid_tokens($type, array $tokens) {
function token_render_array(array $array, array $options = array()) {
$rendered = array();
foreach ($array as $key => $value) {
if ($key[0] === '#') {
if (substr($key, 0, 1) === '#') {
continue;
}
$rendered[] = is_array($value) ? render($value) : (string) $value;
Expand Down
122 changes: 122 additions & 0 deletions core/misc/jquery-html-prefilter-3.5.0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* For jQuery versions less than 3.5.0, this replaces the jQuery.htmlPrefilter()
* function with one that fixes these security vulnerabilities while also
* retaining the pre-3.5.0 behavior where it's safe to do so.
* - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11022
* - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11023
*
* Backdrop includes jQuery 1.12.4, the last stable version in the 1.x branch.
* This incorporates only the fix needed for that version, and so is simpler
* than the respective port for Drupal 7.
*/

(function (jQuery) {

// Parts of this backport differ by jQuery version.
var versionParts = jQuery.fn.jquery.split('.');
var majorVersion = parseInt(versionParts[0]);
var minorVersion = parseInt(versionParts[1]);

// No backport is needed if we're already on jQuery 3.5 or higher.
if ( (majorVersion > 3) || (majorVersion === 3 && minorVersion >= 5) ) {
return;
}

// Prior to jQuery 3.5, jQuery converted XHTML-style self-closing tags to
// their XML equivalent: e.g., "<div />" to "<div></div>". This is
// problematic for several reasons, including that it's vulnerable to XSS
// attacks. However, since this was jQuery's behavior for many years, many
// Drupal modules and jQuery plugins may be relying on it. Therefore, we
// preserve that behavior, but for a limited set of tags only, that we believe
// to not be vulnerable. This is the set of HTML tags that satisfy all of the
// following conditions:
// - In DOMPurify's list of HTML tags. If an HTML tag isn't safe enough to
// appear in that list, then we don't want to mess with it here either.
// @see https://github.com/cure53/DOMPurify/blob/2.0.11/dist/purify.js#L128
// - A normal element (not a void, template, text, or foreign element).
// @see https://html.spec.whatwg.org/multipage/syntax.html#elements-2
// - An element that is still defined by the current HTML specification
// (not a deprecated element), because we do not want to rely on how
// browsers parse deprecated elements.
// @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element
// - Not 'html', 'head', or 'body', because this pseudo-XHTML expansion is
// designed for fragments, not entire documents.
// - Not 'colgroup', because due to an idiosyncrasy of jQuery's original
// regular expression, it didn't match on colgroup, and we don't want to
// introduce a behavior change for that.
var selfClosingTagsToReplace = [
'a', 'abbr', 'address', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo',
'blockquote', 'button', 'canvas', 'caption', 'cite', 'code', 'data',
'datalist', 'dd', 'del', 'details', 'dfn', 'div', 'dl', 'dt', 'em',
'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3',
'h4', 'h5', 'h6', 'header', 'hgroup', 'i', 'ins', 'kbd', 'label', 'legend',
'li', 'main', 'map', 'mark', 'menu', 'meter', 'nav', 'ol', 'optgroup',
'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt',
'ruby', 's', 'samp', 'section', 'select', 'small', 'source', 'span',
'strong', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th',
'thead', 'time', 'tr', 'u', 'ul', 'var', 'video'
];

// Define regular expressions for <TAG/> and <TAG ATTRIBUTES/>. Doing this as
// two expressions makes it easier to target <a/> without also targeting
// every tag that starts with "a".
var xhtmlRegExpGroup = '(' + selfClosingTagsToReplace.join('|') + ')';
var whitespace = '[\\x20\\t\\r\\n\\f]';
var rxhtmlTagWithoutSpaceOrAttributes = new RegExp('<' + xhtmlRegExpGroup + '\\/>', 'gi');
var rxhtmlTagWithSpaceAndMaybeAttributes = new RegExp('<' + xhtmlRegExpGroup + '(' + whitespace + '[^>]*)\\/>', 'gi');

// jQuery 3.5 also fixed a vulnerability for when </select> appears within
// an <option> or <optgroup>, but it did that in local code that we can't
// backport directly. Instead, we filter such cases out. To do so, we need to
// determine when jQuery would otherwise invoke the vulnerable code, which it
// uses this regular expression to determine. The regular expression changed
// for version 3.0.0 and changed again for 3.4.0.
// @see https://github.com/jquery/jquery/blob/1.12.4/dist/jquery.js#L4432
// @see https://github.com/jquery/jquery/blob/3.0.0/dist/jquery.js#L4584
var rtagName;
if (majorVersion < 3) {
rtagName = /<([\w:]+)/;
}
else if (minorVersion < 4) {
rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i;
}
else {
rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i;
}

// The regular expression that jQuery uses to determine which self-closing
// tags to expand to open and close tags. This is vulnerable, because it
// matches all tag names except the few excluded ones. We only use this
// expression for determining vulnerability. The expression changed for
// version 3, but we only need to check for vulnerability in versions 1 and 2,
// so we use the expression from those versions.
// @see https://github.com/jquery/jquery/blob/1.12.4/dist/jquery.js#L5874
var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi;

jQuery.extend({
htmlPrefilter: function (html) {
// This is how jQuery determines the first tag in the HTML.
// @see https://github.com/jquery/jquery/blob/1.12.4/dist/jquery.js#L6353
var tag = ( rtagName.exec( html ) || [ "", "" ] )[ 1 ].toLowerCase();

// It is not valid HTML for <option> or <optgroup> to have <select> as
// either a descendant or sibling, and attempts to inject one can cause
// XSS on jQuery versions before 3.5. Since this is invalid HTML and a
// possible XSS attack, reject the entire string.
// @see https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11023
if ((tag === 'option' || tag === 'optgroup') && html.match(/<\/?select/i)) {
html = '';
}

// Retain jQuery's prior to 3.5 conversion of pseudo-XHTML, but for only
// the tags in the `selfClosingTagsToReplace` list defined above.
// @see https://github.com/jquery/jquery/blob/1.12.4/dist/jquery.js#L6130
// @see https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11022
html = html.replace(rxhtmlTagWithoutSpaceOrAttributes, "<$1></$1>");
html = html.replace(rxhtmlTagWithSpaceAndMaybeAttributes, "<$1$2></$1>");

return html;
}
});

})(jQuery);
4 changes: 4 additions & 0 deletions core/modules/admin_bar/admin_bar.inc
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,10 @@ function _admin_bar_flush_cache($name = NULL) {
break;

case 'assets':
// Rebuild all color palettes.
if (module_exists('color')) {
color_rebuild_settings();
}
// Change query-strings on css/js files to enforce reload for all users.
_backdrop_flush_css_js();

Expand Down
2 changes: 1 addition & 1 deletion core/modules/ckeditor/tests/ckeditor.test
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class CKEditorTestCase extends BackdropWebTestCase {
);
$this->backdropPost('admin/config/content/formats/ckeditor', array(
'editor_settings[toolbar]' => json_encode($toolbar),
'filters[filter_html][settings][allowed_html]' => '<a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <h3> <h4> <h5> <p> <img> <figure> <figcaption> <table> <thead> <tbody> <tr> <td> <th>',
'allowed_html' => '<a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <h3> <h4> <h5> <p> <img> <figure> <figcaption> <table> <thead> <tbody> <tr> <td> <th>',
), t('Save configuration'));
$this->backdropGet('node/add/article');
$settings = $this->backdropGetSettings();
Expand Down
Loading

0 comments on commit d38dedc

Please sign in to comment.