diff --git a/composer.lock b/composer.lock index 96d6552370..45d304926a 100644 --- a/composer.lock +++ b/composer.lock @@ -89,16 +89,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.52", + "version": "1.3.55", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "134b25a63d83a80ae128aedc9a99987e064b4382" + "reference": "21084eb9e6c117f5236969532d00ed2750cd1617" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/134b25a63d83a80ae128aedc9a99987e064b4382", - "reference": "134b25a63d83a80ae128aedc9a99987e064b4382", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/21084eb9e6c117f5236969532d00ed2750cd1617", + "reference": "21084eb9e6c117f5236969532d00ed2750cd1617", "shasum": "" }, "require": { @@ -107,7 +107,7 @@ "php": ">=5.3.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~1.0", + "friendsofphp/php-cs-fixer": "~2.0", "matthiasmullie/scrapbook": "~1.0", "phpunit/phpunit": "~4.8" }, @@ -136,7 +136,7 @@ "role": "Developer" } ], - "description": "CSS & JS minifier", + "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", "homepage": "http://www.minifier.org", "keywords": [ "JS", @@ -145,7 +145,7 @@ "minifier", "minify" ], - "time": "2017-09-15T13:02:11+00:00" + "time": "2017-10-25T11:13:12+00:00" }, { "name": "matthiasmullie/path-converter", @@ -349,16 +349,16 @@ }, { "name": "simplepie/simplepie", - "version": "1.5", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/simplepie/simplepie.git", - "reference": "5de5551953f95feef12cf355a7a26a70f94aa3ab" + "reference": "db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplepie/simplepie/zipball/5de5551953f95feef12cf355a7a26a70f94aa3ab", - "reference": "5de5551953f95feef12cf355a7a26a70f94aa3ab", + "url": "https://api.github.com/repos/simplepie/simplepie/zipball/db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e", + "reference": "db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "feeds", "rss" ], - "time": "2017-04-17T07:29:31+00:00" + "time": "2017-11-12T02:03:34+00:00" }, { "name": "swiftmailer/swiftmailer", diff --git a/system/config/constants.php b/system/config/constants.php index 1daeae46bd..459ef048aa 100644 --- a/system/config/constants.php +++ b/system/config/constants.php @@ -13,7 +13,7 @@ * Core version */ define('VERSION', '3.5'); -define('BUILD', '30'); +define('BUILD', '31'); define('LONG_TERM_SUPPORT', true); diff --git a/system/docs/CHANGELOG.md b/system/docs/CHANGELOG.md index 21f79a09b7..94eeefeafa 100644 --- a/system/docs/CHANGELOG.md +++ b/system/docs/CHANGELOG.md @@ -1,6 +1,13 @@ Contao Open Source CMS changelog ================================ +Version 3.5.31 (2017-11-15) +--------------------------- + +### Fixed +Prevent SQL injections in the back end search panel (see CVE-2017-16558). + + Version 3.5.30 (2017-10-06) --------------------------- diff --git a/system/modules/calendar/languages/pl/default.xlf b/system/modules/calendar/languages/pl/default.xlf index cfd0330f7c..a219eb69ba 100644 --- a/system/modules/calendar/languages/pl/default.xlf +++ b/system/modules/calendar/languages/pl/default.xlf @@ -15,6 +15,7 @@ – + There are no events on this day. diff --git a/system/modules/core/drivers/DC_Table.php b/system/modules/core/drivers/DC_Table.php index 4baef3ffca..7494c3feab 100644 --- a/system/modules/core/drivers/DC_Table.php +++ b/system/modules/core/drivers/DC_Table.php @@ -4943,23 +4943,33 @@ protected function searchMenu() // Store search value in the current session if (\Input::post('FORM_SUBMIT') == 'tl_filters') { - $session['search'][$this->strTable]['value'] = ''; - $session['search'][$this->strTable]['field'] = \Input::post('tl_field', true); + $strField = \Input::post('tl_field', true); + $strKeyword = ltrim(\Input::postRaw('tl_value'), '*'); + + if ($strField && !in_array($strField, $searchFields, true)) + { + $strField = ''; + $strKeyword = ''; + } // Make sure the regular expression is valid - if (\Input::postRaw('tl_value') != '') + if ($strField && $strKeyword) { try { - $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE " . \Input::post('tl_field', true) . " REGEXP ?") + $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE " . $strField . " REGEXP ?") ->limit(1) - ->execute(\Input::postRaw('tl_value')); - - $session['search'][$this->strTable]['value'] = \Input::postRaw('tl_value'); + ->execute($strKeyword); + } + catch (\Exception $e) + { + $strKeyword = ''; } - catch (\Exception $e) {} } + $session['search'][$this->strTable]['field'] = $strField; + $session['search'][$this->strTable]['value'] = $strKeyword; + $this->Session->setData($session); } @@ -5060,7 +5070,7 @@ protected function sortMenu() $strSort = \Input::post('tl_sort'); // Validate the user input (thanks to aulmn) (see #4971) - if (in_array($strSort, $sortingFields)) + if (in_array($strSort, $sortingFields, true)) { $session['sorting'][$this->strTable] = in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$strSort]['flag'], array(2, 4, 6, 8, 10, 12)) ? "$strSort DESC" : $strSort; $this->Session->setData($session); diff --git a/system/modules/core/languages/pl/tl_files.xlf b/system/modules/core/languages/pl/tl_files.xlf index 772510129c..9a7d8621af 100644 --- a/system/modules/core/languages/pl/tl_files.xlf +++ b/system/modules/core/languages/pl/tl_files.xlf @@ -151,7 +151,7 @@ New folder - Nowy szablon + Nowy folder Create a new folder diff --git a/system/modules/core/languages/pl/tl_settings.xlf b/system/modules/core/languages/pl/tl_settings.xlf index 1287e89564..3bbbf7430f 100644 --- a/system/modules/core/languages/pl/tl_settings.xlf +++ b/system/modules/core/languages/pl/tl_settings.xlf @@ -335,6 +335,7 @@ If the width of an image or movie exceeds this value, it will be adjusted automatically. Set to 0 to disable the limit. + Jeśli szerokość obrazka lub filmu przekroczy tą wartość, element zostanie automatycznie dostosowany. Wprowadź 0, aby wyłączyć limit. JPG thumbnail quality diff --git a/system/modules/core/library/Contao/StringUtil.php b/system/modules/core/library/Contao/StringUtil.php index 940a99fc8e..29bd89c3d8 100644 --- a/system/modules/core/library/Contao/StringUtil.php +++ b/system/modules/core/library/Contao/StringUtil.php @@ -605,13 +605,13 @@ function (array $matches) use ($arrData) $blnCurrent = $arrStack[count($arrStack) - 1]; $blnCurrentIf = $arrIfStack[count($arrIfStack) - 1]; - if (strncmp($strTag, '{if', 3) === 0) + if (strncmp($strTag, '{if ', 4) === 0) { $blnExpression = $evaluateExpression(substr($strTag, 4, -1)); $arrStack[] = $blnCurrent && $blnExpression; $arrIfStack[] = $blnExpression; } - elseif (strncmp($strTag, '{elseif', 7) === 0) + elseif (strncmp($strTag, '{elseif ', 8) === 0) { $blnExpression = $evaluateExpression(substr($strTag, 8, -1)); array_pop($arrStack); diff --git a/system/modules/listing/modules/ModuleListing.php b/system/modules/listing/modules/ModuleListing.php index 97032510d5..d4038f27bd 100644 --- a/system/modules/listing/modules/ModuleListing.php +++ b/system/modules/listing/modules/ModuleListing.php @@ -96,39 +96,42 @@ protected function compile() return; } - - /** - * Add the search menu - */ + // Add the search menu $strWhere = ''; $varKeyword = ''; $strOptions = ''; + $strSearch = \Input::get('search'); + $strFor = \Input::get('for'); + $arrFields = trimsplit(',', $this->list_fields); + $arrSearchFields = trimsplit(',', $this->list_search); $this->Template->searchable = false; - $arrSearchFields = trimsplit(',', $this->list_search); if (!empty($arrSearchFields) && is_array($arrSearchFields)) { $this->Template->searchable = true; - if (\Input::get('search') && \Input::get('for')) + if ($strSearch && !in_array($strSearch, $arrSearchFields, true)) + { + $strSearch = ''; + $strFor = ''; + } + + if ($strSearch && $strFor) { - $varKeyword = '%' . \Input::get('for') . '%'; - $strWhere = (!$this->list_where ? " WHERE " : " AND ") . \Input::get('search') . " LIKE ?"; + $varKeyword = '%' . $strFor . '%'; + $strWhere = (!$this->list_where ? " WHERE " : " AND ") . $strSearch . " LIKE ?"; } foreach ($arrSearchFields as $field) { - $strOptions .= ' ' . "\n"; + $strOptions .= ' ' . "\n"; } } $this->Template->search_fields = $strOptions; - - /** - * Get the total number of records - */ + // Get the total number of records $strQuery = "SELECT COUNT(*) AS count FROM " . $this->list_table; if ($this->list_where) @@ -136,16 +139,13 @@ protected function compile() $strQuery .= " WHERE (" . $this->list_where . ")"; } - $strQuery .= $strWhere; + $strQuery .= $strWhere; $objTotal = $this->Database->prepare($strQuery)->execute($varKeyword); - - /** - * Validate the page count - */ + // Validate the page count $id = 'page_l' . $this->id; - $page = (\Input::get($id) !== null) ? \Input::get($id) : 1; - $per_page = \Input::get('per_page') ?: $this->perPage; + $page = (\Input::get($id) !== null) ? (int) \Input::get($id) : 1; + $per_page = (int) \Input::get('per_page') ?: $this->perPage; // Thanks to Hagen Klemp (see #4485) if ($per_page > 0 && ($page < 1 || $page > max(ceil($objTotal->count/$per_page), 1))) @@ -158,10 +158,7 @@ protected function compile() $objHandler->generate($objPage->id); } - - /** - * Get the selected records - */ + // Get the selected records $strQuery = "SELECT " . $this->strPk . "," . $this->list_fields; if ($this->list_info_where) @@ -183,16 +180,30 @@ protected function compile() return $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'date' || $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'time' || $GLOBALS['TL_DCA'][$this->list_table]['fields'][$field]['eval']['rgxp'] == 'datim'; }; + $order_by = \Input::get('order_by'); + + if ($order_by && !in_array($order_by, $arrFields, true)) + { + $order_by = ''; + } + + $sort = \Input::get('sort'); + + if ($sort && !in_array($sort, array('asc', 'desc'))) + { + $sort = ''; + } + // Order by - if (\Input::get('order_by')) + if ($order_by) { - if ($isInt(\Input::get('order_by'))) + if ($isInt($order_by)) { - $strQuery .= " ORDER BY CAST(" . \Input::get('order_by') . " AS SIGNED) " . \Input::get('sort'); + $strQuery .= " ORDER BY CAST(" . $order_by . " AS SIGNED) " . $sort; } else { - $strQuery .= " ORDER BY " . \Input::get('order_by') . ' ' . \Input::get('sort'); + $strQuery .= " ORDER BY " . $order_by . ' ' . $sort; } } elseif ($this->list_sort) @@ -210,9 +221,9 @@ protected function compile() $objDataStmt = $this->Database->prepare($strQuery); // Limit - if (\Input::get('per_page')) + if ($per_page) { - $objDataStmt->limit(\Input::get('per_page'), (($page - 1) * $per_page)); + $objDataStmt->limit($per_page, (($page - 1) * $per_page)); } elseif ($this->perPage) { @@ -221,10 +232,7 @@ protected function compile() $objData = $objDataStmt->execute($varKeyword); - - /** - * Prepare the URL - */ + // Prepare the URL $strUrl = preg_replace('/\?.*$/', '', \Environment::get('request')); $blnQuery = false; @@ -240,13 +248,9 @@ protected function compile() $this->Template->url = $strUrl; $strVarConnector = ($blnQuery || \Config::get('disableAlias')) ? '&' : '?'; - - /** - * Prepare the data arrays - */ + // Prepare the data arrays $arrTh = array(); $arrTd = array(); - $arrFields = trimsplit(',', $this->list_fields); // THEAD for ($i=0, $c=count($arrFields); $i<$c; $i++) @@ -262,10 +266,10 @@ protected function compile() $strField = strlen($label = $GLOBALS['TL_DCA'][$this->list_table]['fields'][$arrFields[$i]]['label'][0]) ? $label : $arrFields[$i]; // Add a CSS class to the order_by column - if (\Input::get('order_by') == $arrFields[$i]) + if ($order_by == $arrFields[$i]) { - $sort = (\Input::get('sort') == 'asc') ? 'desc' : 'asc'; - $class = ' sorted ' . \Input::get('sort'); + $sort = ($sort == 'asc') ? 'desc' : 'asc'; + $class = ' sorted ' . $sort; } $arrTh[] = array @@ -310,7 +314,7 @@ protected function compile() $arrTd[$class][$k] = array ( 'raw' => $v, - 'content' => ($value ? $value : ' '), + 'content' => $value ?: ' ', 'class' => 'col_' . $j . (($j++ == 0) ? ' col_first' : '') . ($this->list_info ? '' : (($j >= (count($arrRows[$i]) - 1)) ? ' col_last' : '')), 'id' => $arrRows[$i][$this->strPk], 'field' => $k, @@ -323,29 +327,23 @@ protected function compile() $this->Template->thead = $arrTh; $this->Template->tbody = $arrTd; - - /** - * Pagination - */ + // Pagination $objPagination = new \Pagination($objTotal->count, $per_page, \Config::get('maxPaginationLinks'), $id); $this->Template->pagination = $objPagination->generate("\n "); $this->Template->per_page = $per_page; $this->Template->total = $objTotal->count; - - /** - * Template variables - */ + // Template variables $this->Template->action = \Environment::get('indexFreeRequest'); - $this->Template->details = ($this->list_info != '') ? true : false; + $this->Template->details = (bool) $this->list_info; $this->Template->search_label = specialchars($GLOBALS['TL_LANG']['MSC']['search']); $this->Template->per_page_label = specialchars($GLOBALS['TL_LANG']['MSC']['list_perPage']); $this->Template->fields_label = $GLOBALS['TL_LANG']['MSC']['all_fields'][0]; $this->Template->keywords_label = $GLOBALS['TL_LANG']['MSC']['keywords']; - $this->Template->search = \Input::get('search'); - $this->Template->for = \Input::get('for'); - $this->Template->order_by = \Input::get('order_by'); - $this->Template->sort = \Input::get('sort'); + $this->Template->search = $strSearch; + $this->Template->for = $strFor; + $this->Template->order_by = $order_by; + $this->Template->sort = $sort; $this->Template->col_last = 'col_' . $j; } diff --git a/system/modules/repository/classes/RepositorySettings.php b/system/modules/repository/classes/RepositorySettings.php index 0cd0e40cf5..02aefd8c6a 100644 --- a/system/modules/repository/classes/RepositorySettings.php +++ b/system/modules/repository/classes/RepositorySettings.php @@ -17,6 +17,7 @@ // valid core versions in descending order define('REPOSITORY_COREVERSIONS', + '30050319,30050319;'. // 3.5.31 '30050309,30050309;'. // 3.5.30 '30050299,30050299;'. // 3.5.29 '30050289,30050289;'. // 3.5.28