Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpmyadmin/phpmyadmin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Bennetch <bennetch@gmail.com>2016-11-24 19:03:58 +0300
committerIsaac Bennetch <bennetch@gmail.com>2016-11-24 19:03:58 +0300
commit253894e2995ae4175f4429bf5cdaedfb6a722988 (patch)
tree7fbb8780941acfa4ad44e1a355ece5a96ac319e7
parent637d55bb4459ffceae9a5d0be36ab022ac583e10 (diff)
parent5daee71272efd87a24fe58f90303e82a5b6caf6d (diff)
Resolve merge conflicts with ChangeLogRELEASE_4_6_5
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
-rw-r--r--ChangeLog16
-rw-r--r--README2
-rw-r--r--doc/conf.py2
-rw-r--r--import.php4
-rw-r--r--index.php2
-rw-r--r--js/config.js4
-rw-r--r--js/microhistory.js13
-rw-r--r--libraries/Config.php2
-rw-r--r--libraries/DbQbe.php5
-rw-r--r--libraries/Error.php2
-rw-r--r--libraries/ErrorHandler.php9
-rw-r--r--libraries/Message.php25
-rw-r--r--libraries/SavedSearches.php10
-rw-r--r--libraries/Tracker.php3
-rw-r--r--libraries/VersionInformation.php8
-rw-r--r--libraries/core.lib.php40
-rw-r--r--libraries/export.lib.php8
-rw-r--r--libraries/ip_allow_deny.lib.php4
-rw-r--r--libraries/plugins/AuthenticationPlugin.php24
-rw-r--r--libraries/plugins/auth/AuthenticationConfig.php8
-rw-r--r--libraries/plugins/auth/AuthenticationCookie.php12
-rw-r--r--libraries/plugins/auth/AuthenticationHttp.php15
-rw-r--r--libraries/tbl_partition_definition.inc.php40
-rw-r--r--libraries/tracking.lib.php6
-rw-r--r--prefs_manage.php2
-rw-r--r--test/classes/ErrorTest.php2
-rw-r--r--test/classes/MessageTest.php3
-rw-r--r--test/libraries/core/PMA_isAllowedDomain_test.php3
-rw-r--r--test/libraries/core/PMA_safeUnserialize_test.php1
-rw-r--r--test/libraries/core/PMA_sanitizeMySQLHost_test.php1
30 files changed, 197 insertions, 79 deletions
diff --git a/ChangeLog b/ChangeLog
index 82f4832e5a..5f120e39f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,7 @@
phpMyAdmin - ChangeLog
======================
-4.6.5 (not yet released)
+4.6.5 (2016-11-24)
- issue Remove potentionally license problematic sRGB profile
- issue #12459 Display read only fields as read only when editing
- issue #12384 Fix expanding of navigation pane when clicking on database
@@ -93,6 +93,20 @@ phpMyAdmin - ChangeLog
- issue #12361 Fix self SQL injection in table-specific privileges
- issue #12698 Add link to release notes and download on new version notification
- issue #12712 Error when trying to setup replication (fatal error in call to an old PMA_DBI_connect function)
+- issue [security] Unsafe generation of $cfg['blowfish_secret'], see PMASA-2016-58
+- issue [security] phpMyAdmin's phpinfo functionality is removed, see PMASA-2016-59
+- issue [security] AllowRoot and allow/deny rule bypass with specially-crafted username, see PMASA-2016-60
+- issue [security] Username matching weaknesses with allow/deny rules, see PMASA-2016-61
+- issue [security] Possible to bypass logout timeout, see PMASA-2016-62
+- issue [security] Full path disclosure (FPD) weaknesses, see PMASA-2016-63
+- issue [security] Multiple XSS weaknesses, see PMASA-2016-64
+- issue [security] Multiple denial-of-service (DOS) vulnerabilities, see PMASA-2016-65
+- issue [security] Possible to bypass white-list protection for URL redirection, see PMASA-2016-66
+- issue [security] BBCode injection to login page, see PMASA-2016-67
+- issue [security] Denial-of-service (DOS) vulnerability in table partitioning, see PMASA-2016-68
+- issue [security] Multiple SQL injection vulnerabilities, see PMASA-2016-69
+- issue [security] Incorrect serialized string parsing, see PMASA-2016-70
+- issue [security] CSRF token not stripped from the URL, see PMASA-2016-71
4.6.4 (2016-08-16)
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
diff --git a/README b/README
index 6e7b903c38..48afce6480 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
phpMyAdmin - Readme
===================
-Version 4.6.5-dev
+Version 4.6.5
A web interface for MySQL and MariaDB.
diff --git a/doc/conf.py b/doc/conf.py
index e87f80a90c..48317aeb16 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -51,7 +51,7 @@ copyright = u'2012 - 2016, The phpMyAdmin devel team'
# built documents.
#
# The short X.Y version.
-version = '4.6.5-dev'
+version = '4.6.5'
# The full version, including alpha/beta/rc tags.
release = version
diff --git a/import.php b/import.php
index b6db86fc00..9f41389712 100644
--- a/import.php
+++ b/import.php
@@ -616,8 +616,8 @@ if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE && isset($charset_of_fil
// Something to skip? (because timeout has passed)
if (! $error && isset($_POST['skip'])) {
- $original_skip = $skip = $_POST['skip'];
- while ($skip > 0) {
+ $original_skip = $skip = intval($_POST['skip']);
+ while ($skip > 0 && ! $finished) {
PMA_importGetNextChunk($skip < $read_limit ? $skip : $read_limit);
// Disable read progressivity, otherwise we eat all memory!
$read_multiply = 1;
diff --git a/index.php b/index.php
index 62c0a4d63f..7643c68407 100644
--- a/index.php
+++ b/index.php
@@ -389,7 +389,7 @@ PMA_printListItem(
PMA_printListItem(
__('Official Homepage'),
'li_pma_homepage',
- PMA_linkURL('https://www.phpMyAdmin.net/'),
+ PMA_linkURL('https://www.phpmyadmin.net/'),
null,
'_blank'
);
diff --git a/js/config.js b/js/config.js
index d3d0c5f840..7a0f4bf53f 100644
--- a/js/config.js
+++ b/js/config.js
@@ -625,9 +625,9 @@ AJAX.registerOnload('config.js', function () {
var tab_check_fnc = function () {
if (location.hash != prev_hash) {
prev_hash = location.hash;
- if (location.hash.match(/^#tab_[a-zA-Z0-9_]+/)) {
+ if (prev_hash.match(/^#tab_[a-zA-Z0-9_]+$/)) {
// session ID is sometimes appended here
- var hash = location.hash.substr(5).split('&')[0];
+ var hash = prev_hash.substr(5).split('&')[0];
if ($('#' + hash).length) {
setTab(hash);
}
diff --git a/js/microhistory.js b/js/microhistory.js
index 60bb207147..4263cd0eef 100644
--- a/js/microhistory.js
+++ b/js/microhistory.js
@@ -280,15 +280,16 @@ PMA_SetUrlHash = (function (jQuery, window) {
/**
* Start initialisation
*/
- if (window.location.hash.substring(0, 8) == '#PMAURL-') {
+ var urlhash = window.location.hash;
+ if (urlhash.substring(0, 8) == '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
- var colon_position = window.location.hash.indexOf(':');
- var questionmark_position = window.location.hash.indexOf('?');
+ var colon_position = urlhash.indexOf(':');
+ var questionmark_position = urlhash.indexOf('?');
if (colon_position != -1 && questionmark_position != -1 && colon_position < questionmark_position) {
- var hash_url = window.location.hash.substring(colon_position + 1, questionmark_position);
+ var hash_url = urlhash.substring(colon_position + 1, questionmark_position);
if (PMA_gotoWhitelist.indexOf(hash_url) != -1) {
- window.location = window.location.hash.substring(
+ window.location = urlhash.substring(
colon_position + 1
);
}
@@ -328,4 +329,4 @@ PMA_SetUrlHash = (function (jQuery, window) {
* Publicly exposes a reference to the otherwise private setUrlHash function
*/
return setUrlHash;
-})(jQuery, window); \ No newline at end of file
+})(jQuery, window);
diff --git a/libraries/Config.php b/libraries/Config.php
index b3dce0e5e7..d5b6a386ab 100644
--- a/libraries/Config.php
+++ b/libraries/Config.php
@@ -101,7 +101,7 @@ class Config
*/
public function checkSystem()
{
- $this->set('PMA_VERSION', '4.6.5-dev');
+ $this->set('PMA_VERSION', '4.6.5');
/**
* @deprecated
*/
diff --git a/libraries/DbQbe.php b/libraries/DbQbe.php
index d9d1f3ca21..08eb4cc520 100644
--- a/libraries/DbQbe.php
+++ b/libraries/DbQbe.php
@@ -1940,7 +1940,10 @@ class DbQbe
// sets row count
$rows = PMA_ifSetOr($_REQUEST['rows'], 0, 'numeric');
$criteriaRowAdd = PMA_ifSetOr($_REQUEST['criteriaRowAdd'], 0, 'numeric');
- $this->_criteria_row_count = max($rows + $criteriaRowAdd, 0);
+ $this->_criteria_row_count = min(
+ 100,
+ max($rows + $criteriaRowAdd, 0)
+ );
return $criteriaColumnCount;
}
diff --git a/libraries/Error.php b/libraries/Error.php
index b45afef75a..7a0083864e 100644
--- a/libraries/Error.php
+++ b/libraries/Error.php
@@ -478,7 +478,7 @@ class Error extends Message
/* Probably affected by open_basedir */
if ($dest === FALSE) {
- return $path;
+ return basename($path);
}
$Ahere = explode(
diff --git a/libraries/ErrorHandler.php b/libraries/ErrorHandler.php
index 0e96f8e026..b3e6cf4ea0 100644
--- a/libraries/ErrorHandler.php
+++ b/libraries/ErrorHandler.php
@@ -193,16 +193,19 @@ class ErrorHandler
$this->errors[$error->getHash()] = $error;
switch ($error->getNumber()) {
- case E_USER_NOTICE:
- case E_USER_WARNING:
case E_STRICT:
case E_DEPRECATED:
case E_NOTICE:
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
- case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
+ /* Avoid rendering BB code in PHP errors */
+ $error->setBBCode(false);
+ break;
+ case E_USER_NOTICE:
+ case E_USER_WARNING:
+ case E_USER_ERROR:
// just collect the error
// display is called from outside
break;
diff --git a/libraries/Message.php b/libraries/Message.php
index 1b500aff39..fefd50ff44 100644
--- a/libraries/Message.php
+++ b/libraries/Message.php
@@ -113,6 +113,14 @@ class Message
protected $isDisplayed = false;
/**
+ * Whether to use BB code when displaying.
+ *
+ * @access protected
+ * @var boolean
+ */
+ protected $useBBCode = true;
+
+ /**
* Unique id
*
* @access protected
@@ -236,6 +244,7 @@ class Message
{
$r = new Message('', $type);
$r->setMessage($message);
+ $r->setBBCode(false);
return $r;
}
@@ -393,6 +402,18 @@ class Message
}
/**
+ * Set whether we should use BB Code when rendering.
+ *
+ * @param boolean $useBBCode Use BB Code?
+ *
+ * @return void
+ */
+ public function setBBCode($useBBCode)
+ {
+ $this->useBBCode = $useBBCode;
+ }
+
+ /**
* set raw message (overrides string)
*
* @param string $message A localized string
@@ -647,7 +668,9 @@ class Message
$message = Message::format($message, $this->getParams());
}
- $message = Message::decodeBB($message);
+ if ($this->useBBCode) {
+ $message = Message::decodeBB($message);
+ }
foreach ($this->getAddedMessages() as $add_message) {
$message .= $add_message;
diff --git a/libraries/SavedSearches.php b/libraries/SavedSearches.php
index db80ff75d0..9cd652afaa 100644
--- a/libraries/SavedSearches.php
+++ b/libraries/SavedSearches.php
@@ -160,6 +160,16 @@ class SavedSearches
}
}
+ /* Limit amount of rows */
+ if (!isset($data['rows'])) {
+ $data['rows'] = 0;
+ } else {
+ $data['rows'] = min(
+ max(0, intval($data['rows'])),
+ 100
+ );
+ }
+
for ($i = 0; $i <= $data['rows']; $i++) {
$data['Or' . $i] = $criterias['Or' . $i];
}
diff --git a/libraries/Tracker.php b/libraries/Tracker.php
index 8132503bfa..06b77d03b9 100644
--- a/libraries/Tracker.php
+++ b/libraries/Tracker.php
@@ -144,8 +144,9 @@ class Tracker
static public function getLogComment()
{
$date = date('Y-m-d H:i:s');
+ $user = preg_replace('/\s+/', ' ', $GLOBALS['cfg']['Server']['user']);
- return "# log " . $date . " " . $GLOBALS['cfg']['Server']['user'] . "\n";
+ return "# log " . $date . " " . $user . "\n";
}
/**
diff --git a/libraries/VersionInformation.php b/libraries/VersionInformation.php
index dcfa362991..f256ef70ce 100644
--- a/libraries/VersionInformation.php
+++ b/libraries/VersionInformation.php
@@ -72,7 +72,7 @@ class VersionInformation
CURLOPT_TIMEOUT,
$connection_timeout
);
- $response = curl_exec($curl_handle);
+ $response = @curl_exec($curl_handle);
} else if (ini_get('allow_url_fopen')) {
$context = array(
'http' => array(
@@ -81,12 +81,16 @@ class VersionInformation
)
);
$context = Util::handleContext($context);
- $response = file_get_contents(
+ $response = @file_get_contents(
$file,
false,
stream_context_create($context)
);
}
+ // Check possible failure of getting data
+ if ($response === false) {
+ $response = '{}';
+ }
}
/* Parse response */
diff --git a/libraries/core.lib.php b/libraries/core.lib.php
index ffb0540293..cb7161d281 100644
--- a/libraries/core.lib.php
+++ b/libraries/core.lib.php
@@ -754,10 +754,17 @@ function PMA_linkURL($url)
function PMA_isAllowedDomain($url)
{
$arr = parse_url($url);
- // Avoid URLs without hostname or with credentials
- if (empty($arr['host']) || ! empty($arr['user']) || ! empty($arr['pass'])) {
+ // We need host to be set
+ if (! isset($arr['host']) || strlen($arr['host']) == 0) {
return false;
}
+ // We do not want these to be present
+ $blocked = array('user', 'pass', 'port');
+ foreach ($blocked as $part) {
+ if (isset($arr[$part]) && strlen($arr[$part]) != 0) {
+ return false;
+ }
+ }
$domain = $arr["host"];
$domainWhiteList = array(
/* Include current domain */
@@ -766,6 +773,7 @@ function PMA_isAllowedDomain($url)
'wiki.phpmyadmin.net', 'www.phpmyadmin.net', 'phpmyadmin.net',
'demo.phpmyadmin.net',
'docs.phpmyadmin.net',
+ 'demo.phpmyadmin.net',
/* mysql.com domains */
'dev.mysql.com','bugs.mysql.com',
/* mariadb domains */
@@ -781,7 +789,7 @@ function PMA_isAllowedDomain($url)
/* Following are doubtful ones. */
'mysqldatabaseadministration.blogspot.com',
);
- if (in_array(mb_strtolower($domain), $domainWhiteList)) {
+ if (in_array($domain, $domainWhiteList)) {
return true;
}
@@ -1014,7 +1022,7 @@ if (! function_exists('hash_hmac')) {
/**
* Sanitizes MySQL hostname
*
- * * strips p: prefix
+ * * strips p: prefix(es)
*
* @param string $name User given hostname
*
@@ -1022,14 +1030,32 @@ if (! function_exists('hash_hmac')) {
*/
function PMA_sanitizeMySQLHost($name)
{
- if (strtolower(substr($name, 0, 2)) == 'p:') {
- return substr($name, 2);
+ while (strtolower(substr($name, 0, 2)) == 'p:') {
+ $name = substr($name, 2);
}
return $name;
}
/**
+ * Sanitizes MySQL username
+ *
+ * * strips part behind null byte
+ *
+ * @param string $name User given username
+ *
+ * @return string
+ */
+function PMA_sanitizeMySQLUser($name)
+{
+ $position = strpos($name, chr(0));
+ if ($position !== false) {
+ return substr($name, 0, $position);
+ }
+ return $name;
+}
+
+/**
* Safe unserializer wrapper
*
* It does not unserialize data containing objects
@@ -1062,7 +1088,7 @@ function PMA_safeUnserialize($data)
case 's':
/* string */
// parse sting length
- $strlen = intval($data[$i + 2]);
+ $strlen = intval(substr($data, $i + 2));
// string start
$i = strpos($data, ':', $i + 2);
if ($i === false) {
diff --git a/libraries/export.lib.php b/libraries/export.lib.php
index d8b3fa1bda..7a21795027 100644
--- a/libraries/export.lib.php
+++ b/libraries/export.lib.php
@@ -18,12 +18,10 @@ use PMA\libraries\ZipFile;
*/
function PMA_shutdownDuringExport()
{
- $a = error_get_last();
- if ($a != null && mb_strpos($a['message'], "execution time")) {
- //write in partially downloaded file for future reference of user
- print_r($a);
+ $error = error_get_last();
+ if ($error != null && mb_strpos($error['message'], "execution time")) {
//set session variable to check if there was error while exporting
- $_SESSION['pma_export_error'] = $a['message'];
+ $_SESSION['pma_export_error'] = $error['message'];
}
}
diff --git a/libraries/ip_allow_deny.lib.php b/libraries/ip_allow_deny.lib.php
index bd7c84757b..cc74c16b7c 100644
--- a/libraries/ip_allow_deny.lib.php
+++ b/libraries/ip_allow_deny.lib.php
@@ -194,7 +194,7 @@ function PMA_ipv6MaskTest($test_range, $ip_to_test)
if ($is_single) {
$range_hex = bin2hex(inet_pton($test_range));
- $result = $ip_hex === $range_hex;
+ $result = hash_equals($ip_hex, $range_hex);
return $result;
}
@@ -321,7 +321,7 @@ function PMA_allowDeny($type)
// check for username
if (($rule_data[1] != '%') //wildcarded first
- && ($rule_data[1] != $username)
+ && (! hash_equals($rule_data[1], $username))
) {
continue;
}
diff --git a/libraries/plugins/AuthenticationPlugin.php b/libraries/plugins/AuthenticationPlugin.php
index 33f83f4a63..6063aa98e0 100644
--- a/libraries/plugins/AuthenticationPlugin.php
+++ b/libraries/plugins/AuthenticationPlugin.php
@@ -114,7 +114,7 @@ abstract class AuthenticationPlugin
} else {
$dbi_error = $GLOBALS['dbi']->getError();
if (!empty($dbi_error)) {
- return PMA_sanitize($dbi_error);
+ return htmlspecialchars($dbi_error);
} elseif (isset($GLOBALS['errno'])) {
return '#' . $GLOBALS['errno'] . ' '
. __('Cannot log in to the MySQL server');
@@ -134,4 +134,26 @@ abstract class AuthenticationPlugin
public function handlePasswordChange($password)
{
}
+
+ /**
+ * Store session access time in session.
+ *
+ * Tries to workaround PHP 5 session garbage collection which
+ * looks at the session file's last modified time
+ *
+ * @return void
+ */
+ public function setSessionAccessTime()
+ {
+ if (isset($_REQUEST['access_time'])) {
+ // Ensure access_time is in range <0, LoginCookieValidity + 1>
+ // to avoid excessive extension of validity.
+ //
+ // Negative values can cause session expiry extension
+ // Too big values can cause overflow and lead to same
+ $_SESSION['last_access_time'] = time() - min(max(0, intval($_REQUEST['access_time'])), $GLOBALS['cfg']['LoginCookieValidity'] + 1);
+ } else {
+ $_SESSION['last_access_time'] = time();
+ }
+ }
}
diff --git a/libraries/plugins/auth/AuthenticationConfig.php b/libraries/plugins/auth/AuthenticationConfig.php
index a98263b94f..77bf980d97 100644
--- a/libraries/plugins/auth/AuthenticationConfig.php
+++ b/libraries/plugins/auth/AuthenticationConfig.php
@@ -61,13 +61,7 @@ class AuthenticationConfig extends AuthenticationPlugin
*/
public function authSetUser()
{
- // try to workaround PHP 5 session garbage collection which
- // looks at the session file's last modified time
- if (isset($_REQUEST['access_time'])) {
- $_SESSION['last_access_time'] = time() - $_REQUEST['access_time'];
- } else {
- $_SESSION['last_access_time'] = time();
- }
+ $this->setSessionAccessTime();
return true;
}
diff --git a/libraries/plugins/auth/AuthenticationCookie.php b/libraries/plugins/auth/AuthenticationCookie.php
index 9f9e040206..0d37f4db32 100644
--- a/libraries/plugins/auth/AuthenticationCookie.php
+++ b/libraries/plugins/auth/AuthenticationCookie.php
@@ -301,7 +301,7 @@ class AuthenticationCookie extends AuthenticationPlugin
}
// The user just logged in
- $GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
+ $GLOBALS['PHP_AUTH_USER'] = PMA_sanitizeMySQLUser($_REQUEST['pma_username']);
$GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password'])
? ''
: $_REQUEST['pma_password'];
@@ -408,14 +408,14 @@ class AuthenticationCookie extends AuthenticationPlugin
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
- if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
+ if (! hash_equals($cfg['Server']['user'], $GLOBALS['PHP_AUTH_USER'])) {
foreach ($cfg['Servers'] as $idx => $current) {
if ($current['host'] == $cfg['Server']['host']
&& $current['port'] == $cfg['Server']['port']
&& $current['socket'] == $cfg['Server']['socket']
&& $current['ssl'] == $cfg['Server']['ssl']
&& $current['connect_type'] == $cfg['Server']['connect_type']
- && $current['user'] == $GLOBALS['PHP_AUTH_USER']
+ && hash_equals($current['user'], $GLOBALS['PHP_AUTH_USER'])
) {
$GLOBALS['server'] = $idx;
$cfg['Server'] = $current;
@@ -450,11 +450,7 @@ class AuthenticationCookie extends AuthenticationPlugin
// Avoid showing the password in phpinfo()'s output
unset($GLOBALS['PHP_AUTH_PW']);
unset($_SERVER['PHP_AUTH_PW']);
- if (isset($_REQUEST['access_time'])) {
- $_SESSION['last_access_time'] = time() - $_REQUEST['access_time'];
- } else {
- $_SESSION['last_access_time'] = time();
- }
+ $this->setSessionAccessTime();
}
/**
diff --git a/libraries/plugins/auth/AuthenticationHttp.php b/libraries/plugins/auth/AuthenticationHttp.php
index 3f76a130b5..b4c6f92808 100644
--- a/libraries/plugins/auth/AuthenticationHttp.php
+++ b/libraries/plugins/auth/AuthenticationHttp.php
@@ -165,10 +165,13 @@ class AuthenticationHttp extends AuthenticationPlugin
unset($usr_pass);
}
+ // sanitize username
+ $PHP_AUTH_USER = PMA_sanitizeMySQLUser($PHP_AUTH_USER);
+
// User logged out -> ensure the new username is not the same
$old_usr = isset($_REQUEST['old_usr']) ? $_REQUEST['old_usr'] : '';
- if (!empty($old_usr)
- && (isset($PHP_AUTH_USER) && $old_usr == $PHP_AUTH_USER)
+ if (! empty($old_usr)
+ && (isset($PHP_AUTH_USER) && hash_equals($old_usr, $PHP_AUTH_USER))
) {
$PHP_AUTH_USER = '';
// -> delete user's choices that were stored in session
@@ -202,12 +205,12 @@ class AuthenticationHttp extends AuthenticationPlugin
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
- if ($cfg['Server']['user'] != $PHP_AUTH_USER) {
+ if (! hash_equals($cfg['Server']['user'], $PHP_AUTH_USER)) {
$servers_cnt = count($cfg['Servers']);
for ($i = 1; $i <= $servers_cnt; $i++) {
if (isset($cfg['Servers'][$i])
&& ($cfg['Servers'][$i]['host'] == $cfg['Server']['host']
- && $cfg['Servers'][$i]['user'] == $PHP_AUTH_USER)
+ && hash_equals($cfg['Servers'][$i]['user'], $PHP_AUTH_USER))
) {
$server = $i;
$cfg['Server'] = $cfg['Servers'][$i];
@@ -223,9 +226,7 @@ class AuthenticationHttp extends AuthenticationPlugin
unset($GLOBALS['PHP_AUTH_PW']);
unset($_SERVER['PHP_AUTH_PW']);
- // try to workaround PHP 5 session garbage collection which
- // looks at the session file's last modified time
- $_SESSION['last_access_time'] = time();
+ $this->setSessionAccessTime();
return true;
}
diff --git a/libraries/tbl_partition_definition.inc.php b/libraries/tbl_partition_definition.inc.php
index 3f7602bb05..0ec3dc6f0b 100644
--- a/libraries/tbl_partition_definition.inc.php
+++ b/libraries/tbl_partition_definition.inc.php
@@ -14,17 +14,31 @@ if (!isset($partitionDetails)) {
// Extract some partitioning and subpartitioning parameters from the request
$partitionParams = array(
- 'partition_by', 'partition_expr', 'partition_count',
- 'subpartition_by', 'subpartition_expr', 'subpartition_count'
+ 'partition_by', 'partition_expr',
+ 'subpartition_by', 'subpartition_expr',
);
foreach ($partitionParams as $partitionParam) {
$partitionDetails[$partitionParam] = isset($_REQUEST[$partitionParam])
? $_REQUEST[$partitionParam] : '';
}
+ if (PMA_isValid($_REQUEST['partition_count'], 'numeric')) {
+ // MySQL's limit is 8192, so do not allow more
+ $partition_count = min(intval($_REQUEST['partition_count']), 8192);
+ } else {
+ $partition_count = 0;
+ }
+ $partitionDetails['partition_count'] = $partition_count;
+ if (PMA_isValid($_REQUEST['subpartition_count'], 'numeric')) {
+ // MySQL's limit is 8192, so do not allow more
+ $subpartition_count = min(intval($_REQUEST['subpartition_count']), 8192);
+ } else {
+ $subpartition_count = 0;
+ }
+ $partitionDetails['subpartition_count'] = $subpartition_count;
+
// Only LIST and RANGE type parameters allow subpartitioning
- $partitionDetails['can_have_subpartitions'] = isset($_REQUEST['partition_count'])
- && $_REQUEST['partition_count'] > 1
+ $partitionDetails['can_have_subpartitions'] = $partition_count > 1
&& isset($_REQUEST['partition_by'])
&& ($_REQUEST['partition_by'] == 'RANGE'
|| $_REQUEST['partition_by'] == 'RANGE COLUMNS'
@@ -38,18 +52,17 @@ if (!isset($partitionDetails)) {
|| $_REQUEST['partition_by'] == 'LIST'
|| $_REQUEST['partition_by'] == 'LIST COLUMNS');
- if (PMA_isValid($_REQUEST['partition_count'], 'numeric')
- && $_REQUEST['partition_count'] > 1
- ) { // Has partitions
+ // Has partitions
+ if ($partition_count > 1) {
$partitions = isset($_REQUEST['partitions'])
? $_REQUEST['partitions']
: array();
// Remove details of the additional partitions
// when number of partitions have been reduced
- array_splice($partitions, $_REQUEST['partition_count']);
+ array_splice($partitions, $partition_count);
- for ($i = 0; $i < $_REQUEST['partition_count']; $i++) {
+ for ($i = 0; $i < $partition_count; $i++) {
if (! isset($partitions[$i])) { // Newly added partition
$partitions[$i] = array(
'name' => 'p' . $i,
@@ -85,11 +98,10 @@ if (!isset($partitionDetails)) {
$partition['node_group'] = '';
}
- if (PMA_isValid($_REQUEST['subpartition_count'], 'numeric')
- && $_REQUEST['subpartition_count'] > 1
+ if ($subpartition_count > 1
&& $partitionDetails['can_have_subpartitions'] == true
) { // Has subpartitions
- $partition['subpartition_count'] = $_REQUEST['subpartition_count'];
+ $partition['subpartition_count'] = $subpartition_count;
if (! isset($partition['subpartitions'])) {
$partition['subpartitions'] = array();
@@ -98,9 +110,9 @@ if (!isset($partitionDetails)) {
// Remove details of the additional subpartitions
// when number of subpartitions have been reduced
- array_splice($subpartitions, $_REQUEST['subpartition_count']);
+ array_splice($subpartitions, $subpartition_count);
- for ($j = 0; $j < $_REQUEST['subpartition_count']; $j++) {
+ for ($j = 0; $j < $subpartition_count; $j++) {
if (! isset($subpartitions[$j])) { // Newly added subpartition
$subpartitions[$j] = array(
'name' => $partition['name'] . '_s' . $j,
diff --git a/libraries/tracking.lib.php b/libraries/tracking.lib.php
index b0ee37158e..6e2dace08d 100644
--- a/libraries/tracking.lib.php
+++ b/libraries/tracking.lib.php
@@ -1186,14 +1186,16 @@ function PMA_exportAsFileDownload($entries)
{
@ini_set('url_rewriter.tags', '');
+ // Replace all multiple whitespaces by a single space
+ $table = htmlspecialchars(preg_replace('/\s+/', ' ', $_REQUEST['table']));
$dump = "# " . sprintf(
- __('Tracking report for table `%s`'), htmlspecialchars($_REQUEST['table'])
+ __('Tracking report for table `%s`'), $table
)
. "\n" . "# " . date('Y-m-d H:i:s') . "\n";
foreach ($entries as $entry) {
$dump .= $entry['statement'];
}
- $filename = 'log_' . htmlspecialchars($_REQUEST['table']) . '.sql';
+ $filename = 'log_' . $table . '.sql';
PMA\libraries\Response::getInstance()->disable();
PMA_downloadHeader(
$filename,
diff --git a/prefs_manage.php b/prefs_manage.php
index e17dbba6bc..3d8e9cdfa7 100644
--- a/prefs_manage.php
+++ b/prefs_manage.php
@@ -173,7 +173,7 @@ if (isset($_POST['submit_export'])
$result = PMA_saveUserprefs($cf->getConfigArray());
if ($result === true) {
if ($return_url) {
- $query = explode('&', parse_url($return_url, PHP_URL_QUERY));
+ $query = PMA\libraries\Util::splitURLQuery($return_url);
$return_url = parse_url($return_url, PHP_URL_PATH);
foreach ($query as $q) {
diff --git a/test/classes/ErrorTest.php b/test/classes/ErrorTest.php
index ae2aca6b97..fa5c6e9dce 100644
--- a/test/classes/ErrorTest.php
+++ b/test/classes/ErrorTest.php
@@ -102,7 +102,7 @@ class ErrorTest extends PMATestCase
return array(
array('./ChangeLog', './ChangeLog'),
array(__FILE__, './test/classes/ErrorTest.php'),
- array('./NONEXISTING', './NONEXISTING'),
+ array('./NONEXISTING', 'NONEXISTING'),
);
}
diff --git a/test/classes/MessageTest.php b/test/classes/MessageTest.php
index b330430b5b..203178f09b 100644
--- a/test/classes/MessageTest.php
+++ b/test/classes/MessageTest.php
@@ -110,6 +110,7 @@ class MessageTest extends PMATestCase
{
$this->object = new PMA\libraries\Message('', PMA\libraries\Message::ERROR);
$this->object->setMessage('test<&>');
+ $this->object->setBBCode(false);
$this->assertEquals($this->object, PMA\libraries\Message::rawError('test<&>'));
}
@@ -123,6 +124,7 @@ class MessageTest extends PMATestCase
{
$this->object = new PMA\libraries\Message('', PMA\libraries\Message::NOTICE);
$this->object->setMessage('test<&>');
+ $this->object->setBBCode(false);
$this->assertEquals($this->object, PMA\libraries\Message::rawNotice('test<&>'));
}
@@ -136,6 +138,7 @@ class MessageTest extends PMATestCase
{
$this->object = new PMA\libraries\Message('', PMA\libraries\Message::SUCCESS);
$this->object->setMessage('test<&>');
+ $this->object->setBBCode(false);
$this->assertEquals($this->object, PMA\libraries\Message::rawSuccess('test<&>'));
}
diff --git a/test/libraries/core/PMA_isAllowedDomain_test.php b/test/libraries/core/PMA_isAllowedDomain_test.php
index 586e6bcfb3..9f544c0d9c 100644
--- a/test/libraries/core/PMA_isAllowedDomain_test.php
+++ b/test/libraries/core/PMA_isAllowedDomain_test.php
@@ -43,6 +43,9 @@ class PMA_isAllowedDomain_test extends PHPUnit_Framework_TestCase
array('https://www.phpmyadmin.net/', true),
array('http://duckduckgo.com\\@github.com', false),
array('https://github.com/', true),
+ array('https://github.com:123/', false),
+ array('https://user:pass@github.com:123/', false),
+ array('https://user:pass@github.com/', false),
array('https://server.local/', true),
array('./relative/', false),
);
diff --git a/test/libraries/core/PMA_safeUnserialize_test.php b/test/libraries/core/PMA_safeUnserialize_test.php
index f2710c0792..f589361b93 100644
--- a/test/libraries/core/PMA_safeUnserialize_test.php
+++ b/test/libraries/core/PMA_safeUnserialize_test.php
@@ -44,6 +44,7 @@ class PMA_safeUnserialize_test extends PHPUnit_Framework_TestCase
array('b:0;', false),
array('O:1:"a":1:{s:5:"value";s:3:"100";}', null),
array('O:8:"stdClass":1:{s:5:"field";O:8:"stdClass":0:{}}', null),
+ array('a:2:{i:0;s:90:"1234567890;a345678901234567890123456789012345678901234567890123456789012345678901234567890";i:1;O:8:"stdClass":0:{}}', null),
array(serialize(array(1, 2, 3)), array(1, 2, 3)),
array(serialize('string""'), 'string""'),
array(serialize(array('foo' => 'bar')), array('foo' => 'bar')),
diff --git a/test/libraries/core/PMA_sanitizeMySQLHost_test.php b/test/libraries/core/PMA_sanitizeMySQLHost_test.php
index 1b4404732a..d17ca530d0 100644
--- a/test/libraries/core/PMA_sanitizeMySQLHost_test.php
+++ b/test/libraries/core/PMA_sanitizeMySQLHost_test.php
@@ -40,6 +40,7 @@ class PMA_sanitizeMySQLHost_test extends PHPUnit_Framework_TestCase
{
return array(
array('p:foo.bar', 'foo.bar'),
+ array('p:p:foo.bar', 'foo.bar'),
array('bar.baz', 'bar.baz'),
array('P:example.com', 'example.com'),
);