Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2016-08-17 08:53:21 +02:00
commit b156313c09
94 changed files with 1095 additions and 443 deletions

View File

@ -24,7 +24,46 @@ phpMyAdmin - ChangeLog
- issue #12218 Allow to specify further parameters for control connection
- issue #12162 Show charset for each table on Database structure page
4.6.4 (not yet released)
4.6.5 (not yet released)
4.6.4 (2016-08-16)
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
- issue [security] Improve session cookie code for openid.php and signon.php example files
- issue [security] Full path disclosure in openid.php and signon.php example files
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-30
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-31
- issue [security] Unsafe generation of BlowfishSecret (when not supplied by the user)
- issue [security] Referrer leak when phpinfo is enabled
- issue [security] PHP code injection, see PMASA-2016-32
- issue [security] Full path disclosure, see PMASA-2016-33
- issue [security] SQL injection attack, see PMASA-2016-34
- issue [security] Local file exposure through LOAD DATA LOCAL INFILE, see PMASA-2016-35
- issue [security] Local file exposure through symlinks with UploadDir, see PMASA-2016-36
- issue [security] Path traversal with SaveDir and UploadDir, see PMASA-2016-37
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-38
- issue [security] SQL injection vulnerability as control user, see PMASA-2016-39
- issue [security] SQL injection vulnerability, see PMASA-2016-40
- issue [security] Denial-of-service attack through transformation feature, see PMASA-2016-41
- issue [security] SQL injection vulnerability as control user, see PMASA-2016-42
- issue [security] Verify data before unserializing, see PMASA-2016-43
- issue [security] Use HTTPS for wiki links
- issue Remove Swekey support
- issue [security] SSRF in setup script, see PMASA-2016-44
- issue [security] Denial-of-service attack with $cfg['AllowArbitraryServer'] = true and persistent connections, see PMASA-2016-45
- issue [security] Improve SSL certificate handling
- issue [security] Fix full path disclosure in debugging code
- issue [security] Possible circumvention of IP-based allow/deny rules with IPv6 and proxy server, see PMASA-2016-47
- issue [security] Detect if user is logged in, see PMASA-2016-48
- issue [security] Bypass URL redirection protection, see PMASA-2016-49
- issue [security] Referrer leak, see PMASA-2016-50
- issue [security] Reflected File Download, see PMASA-2016-51
- issue [security] ArbitraryServerRegexp bypass, see PMASA-2016-52
- issue [security] Denial-of-service attack by entering long password, see PMASA-2016-53
- issue [security] Remote code execution vulnerability when running as CGI, see PMASA-2016-054
- issue [security] Administrators could trigger SQL injection attack against users
- issue [security] Denial-of-service attack when PHP uses dbase extension, see PMASA-2016-55
- issue [security] Remove tode execution vulnerability when PHP uses dbase extension, see PMASA-2016-56
- issue [security] Denial-of-service attack by using for loops, see PMASA-2016-46
- issue Include X-Robots-Tag header in responses
- issue Enforce numeric field length when creating table
- issue Fixed invalid Content-Length in some HTTP responses

View File

@ -13,6 +13,7 @@ require 'libraries/common.inc.php';
$response = PMA\libraries\Response::getInstance();
$response->disable();
$response->getHeader()->sendHttpHeaders();
$filename = CHANGELOG_FILE;
@ -155,6 +156,7 @@ echo '</pre>';
var links = document.getElementsByTagName("a");
for(var i = 0; i < links.length; i++) {
links[i].target = "_blank";
links[i].rel = "noopener noreferrer";
}
</script>
</body>

View File

@ -12,7 +12,7 @@
/**
* This is needed for cookie based authentication to encrypt password in
* cookie
* cookie. Needs to be 32 chars long.
*/
$cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

View File

@ -1631,7 +1631,10 @@ Cookie authentication options
The "cookie" auth\_type uses AES algorithm to encrypt the password. If you
are using the "cookie" auth\_type, enter here a random passphrase of your
choice. It will be used internally by the AES algorithm: you wont be
prompted for this passphrase. There is no maximum length for this secret.
prompted for this passphrase.
The secret should be 32 characters long. Using shorter will lead to weaker security
of encrypted cookies, using longer will cause no harm.
.. note::
@ -1991,11 +1994,6 @@ Main panel
You can additionally hide more information by using
:config:option:`$cfg['Servers'][$i]['verbose']`.
.. config:option:: $cfg['ShowPhpInfo']
:type: boolean
:default: false
.. config:option:: $cfg['ShowChgPassword']
:type: boolean
@ -2006,18 +2004,11 @@ Main panel
:type: boolean
:default: true
Defines whether to display the :guilabel:`PHP information` and
Defines whether to display the
:guilabel:`Change password` links and form for creating database or not at
the starting main (right) frame. This setting does not check MySQL commands
entered directly.
Please note that to block the usage of ``phpinfo()`` in scripts, you have to
put this in your :file:`php.ini`:
.. code-block:: ini
disable_functions = phpinfo()
Also note that enabling the :guilabel:`Change password` link has no effect
with config authentication mode: because of the hard coded password value
in the configuration file, end users can't be allowed to change their
@ -3087,7 +3078,6 @@ Developer
Enable to let server present itself as demo server.
This is used for `phpMyAdmin demo server <https://www.phpmyadmin.net/try>`_.
.. _config-examples:
Examples

View File

@ -288,7 +288,8 @@ simple configuration may look like this:
<?php
$cfg['blowfish_secret'] = 'ba17c1ec07d65003'; // use here a value of your choice
// use here a value of your choice at least 32 chars long
$cfg['blowfish_secret'] = '1{dd0`<Q),5XP_:R9UK%%8\"EEcyH#{o';
$i=0;
$i++;

View File

@ -74,11 +74,11 @@ function Die_error($e)
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', false);
session_set_cookie_params(0, '/', '', true, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
session_start();
@session_start();
// Determine realm and return_to
$base = 'http';

View File

@ -12,13 +12,13 @@
*/
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', false);
session_set_cookie_params(0, '/', '', true, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
// Uncomment and change the following line to match your $cfg['SessionSavePath']
//session_save_path('/foobar');
session_start();
@session_start();
/* Was data posted? */
if (isset($_POST['user'])) {
@ -31,7 +31,7 @@ if (isset($_POST['user'])) {
$_SESSION['PMA_single_signon_cfgupdate'] = array('verbose' => 'Signon test');
$id = session_id();
/* Close that session */
session_write_close();
@session_write_close();
/* Redirect to phpMyAdmin (should use absolute URL here!) */
header('Location: ../index.php');
} else {

View File

@ -11,6 +11,11 @@ use PMA\libraries\File;
use PMA\libraries\URL;
use PMA\libraries\Bookmark;
/* Enable LOAD DATA LOCAL INFILE for LDI plugin */
if (isset($_POST['format']) && $_POST['format'] == 'ldi') {
define('PMA_ENABLE_LDI', 1);
}
/**
* Get the variables sent or posted to this script and a core script
*/
@ -445,6 +450,15 @@ if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) {
$import_file = PMA\libraries\Util::userDir($cfg['UploadDir'])
. $local_import_file;
/*
* Do not allow symlinks to avoid security issues
* (user can create symlink to file he can not access,
* but phpMyAdmin can).
*/
if (@is_link($import_file)) {
$import_file = 'none';
}
} elseif (empty($import_file) || ! is_uploaded_file($import_file)) {
$import_file = 'none';
}

View File

@ -321,7 +321,7 @@ if ($server > 0 && $GLOBALS['cfg']['ShowServerInfo']) {
. ' </div>';
}
if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) {
if ($GLOBALS['cfg']['ShowServerInfo']) {
echo '<div class="group">';
echo '<h2>' , __('Web server') , '</h2>';
echo '<ul>';
@ -361,15 +361,6 @@ if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) {
}
}
if ($cfg['ShowPhpInfo']) {
PMA_printListItem(
__('Show PHP information'),
'li_phpinfo',
'phpinfo.php' . $common_url_query,
null,
'_blank'
);
}
echo ' </ul>';
echo ' </div>';
}
@ -523,15 +514,23 @@ if ($GLOBALS['cfg']['LoginCookieStore'] != 0
/**
* Check if user does not have defined blowfish secret and it is being used.
*/
if (! empty($_SESSION['encryption_key'])
&& empty($GLOBALS['cfg']['blowfish_secret'])
) {
trigger_error(
__(
'The configuration file now needs a secret passphrase (blowfish_secret).'
),
E_USER_WARNING
);
if (! empty($_SESSION['encryption_key'])) {
if (empty($GLOBALS['cfg']['blowfish_secret'])) {
trigger_error(
__(
'The configuration file now needs a secret passphrase (blowfish_secret).'
),
E_USER_WARNING
);
}
if (strlen($GLOBALS['cfg']['blowfish_secret']) < 32) {
trigger_error(
__(
'The secret passphrase in configuration (blowfish_secret) is too short.'
),
E_USER_WARNING
);
}
}
/**

View File

@ -4117,7 +4117,16 @@ AJAX.registerOnload('functions.js', function () {
* Load version information asynchronously.
*/
if ($('li.jsversioncheck').length > 0) {
$.getJSON('version_check.php', {'server' : PMA_commonParams.get('server')}, PMA_current_version);
$.ajax({
dataType: "json",
url: 'version_check.php',
method: "POST",
data: {
"server": PMA_commonParams.get('server'),
"token": PMA_commonParams.get('token'),
},
success: PMA_current_version
});
}
if ($('#is_git_revision').length > 0) {

View File

@ -23,7 +23,7 @@ function setDropdownValues($dropdown, values, selectedValue) {
// add an empty string to the beginning for empty selection
values.unshift('');
$.each(values, function () {
optionsAsString += "<option value='" + this + "'" + (selectedValue == this ? " selected='selected'" : "") + ">" + this + "</option>";
optionsAsString += "<option value='" + escapeHtml(this) + "'" + (selectedValue == this ? " selected='selected'" : "") + ">" + escapeHtml(this) + "</option>";
});
$dropdown.append($(optionsAsString));
}

View File

@ -356,10 +356,10 @@ class DbSearch
$html_output .= '<td><a name="delete_search" class="ajax" href="'
. $delete_result_path . '" onclick="deleteResult(\''
. $delete_result_path . '\' , \''
. sprintf(
. Sanitize::escapeJsString(sprintf(
__('Delete the matches for the %s table?'),
htmlspecialchars($each_table)
)
))
. '\');return false;">'
. __('Delete') . '</a></td>';
} else {

View File

@ -117,12 +117,17 @@ class Error extends Message
{
$result = array();
$members = array('file', 'line', 'function', 'class', 'type');
$members = array('line', 'function', 'class', 'type');
foreach ($backtrace as $idx => $step) {
/* Create new backtrace entry */
$result[$idx] = array();
/* Make path relative */
if (isset($step['file'])) {
$result[$idx]['file'] = Error::relPath($step['file']);
}
/* Store members we want */
foreach ($members as $name) {
if (isset($step[$name])) {

View File

@ -420,6 +420,11 @@ class File
$this->setName(
Util::userDir($GLOBALS['cfg']['UploadDir']) . PMA_securePath($name)
);
if (@is_link($this->getName())) {
$this->_error_message = __('File is a symbolic link');
$this->setName(null);
return false;
}
if (! $this->isReadable()) {
$this->_error_message = Message::error(__('File could not be read!'));
$this->setName(null);

View File

@ -35,7 +35,7 @@ class Logging
@syslog(
LOG_WARNING,
'user denied: ' . $user . ' (' . $status . ') from ' .
$_SERVER['REMOTE_ADDR']
PMA_getIp()
);
}
}

View File

@ -98,7 +98,7 @@ class RecentFavoriteTable
// Read from phpMyAdmin database, if recent tables is not in session
$sql_query
= " SELECT `tables` FROM " . $this->_getPmaTable() .
" WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'";
" WHERE `username` = '" . Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'";
$return = array();
$result = PMA_queryAsControlUser($sql_query, false);
@ -121,7 +121,7 @@ class RecentFavoriteTable
$username = $GLOBALS['cfg']['Server']['user'];
$sql_query
= " REPLACE INTO " . $this->_getPmaTable() . " (`username`, `tables`)" .
" VALUES ('" . $username . "', '"
" VALUES ('" . Util::sqlAddSlashes($username) . "', '"
. Util::sqlAddSlashes(
json_encode($this->_tables)
) . "')";

View File

@ -60,6 +60,13 @@ class Response
* @var bool
*/
private $_isAjax;
/**
* Whether response object is disabled
*
* @access private
* @var bool
*/
private $_isDisabled;
/**
* Whether we are servicing an ajax request for a page
* that was fired using the generic page handler in JS.
@ -102,6 +109,7 @@ class Response
$this->_isSuccess = true;
$this->_isAjax = false;
$this->_isAjaxPage = false;
$this->_isDisabled = false;
if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
$this->_isAjax = true;
}
@ -174,6 +182,7 @@ class Response
{
$this->_header->disable();
$this->_footer->disable();
$this->_isDisabled = true;
}
/**
@ -277,6 +286,12 @@ class Response
*/
private function _ajaxResponse()
{
/* Avoid wrapping in case we're disabled */
if ($this->_isDisabled) {
echo $this->_getDisplay();
return;
}
if (! isset($this->_JSON['message'])) {
$this->_JSON['message'] = $this->_getDisplay();
} else if ($this->_JSON['message'] instanceof Message) {

View File

@ -64,6 +64,9 @@ class Sanitize
$target = '';
if (! empty($found[3])) {
$target = ' target="' . $found[3] . '"';
if ($found[3] == '_blank') {
$target .= ' rel="noopener noreferrer"';
}
}
/* Construct url */

View File

@ -1460,7 +1460,7 @@ class Table
// Read from phpMyAdmin database
$sql_query = " SELECT `prefs` FROM " . $pma_table
. " WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'"
. " WHERE `username` = '" . Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `db_name` = '" . Util::sqlAddSlashes($this->_db_name) . "'"
. " AND `table_name` = '" . Util::sqlAddSlashes($this->_name) . "'";
@ -1488,7 +1488,7 @@ class Table
$username = $GLOBALS['cfg']['Server']['user'];
$sql_query = " REPLACE INTO " . $pma_table
. " (username, db_name, table_name, prefs) VALUES ('"
. $username . "', '" . $secureDbName
. Util::sqlAddSlashes($username) . "', '" . $secureDbName
. "', '" . Util::sqlAddSlashes($this->_name) . "', '"
. Util::sqlAddSlashes(json_encode($this->uiprefs)) . "')";

View File

@ -2687,7 +2687,7 @@ class Util
$dir .= '/';
}
return str_replace('%u', $GLOBALS['cfg']['Server']['user'], $dir);
return str_replace('%u', PMA_securePath($GLOBALS['cfg']['Server']['user']), $dir);
}
/**

View File

@ -51,20 +51,7 @@ class VersionInformation
session_write_close();
}
$file = 'https://www.phpmyadmin.net/home_page/version.json';
if (ini_get('allow_url_fopen')) {
$context = array(
'http' => array(
'request_fulluri' => true,
'timeout' => $connection_timeout,
)
);
$context = Util::handleContext($context);
$response = file_get_contents(
$file,
false,
stream_context_create($context)
);
} else if (function_exists('curl_init')) {
if (function_exists('curl_init')) {
$curl_handle = curl_init($file);
if ($curl_handle === false) {
return null;
@ -86,6 +73,19 @@ class VersionInformation
$connection_timeout
);
$response = curl_exec($curl_handle);
} else if (ini_get('allow_url_fopen')) {
$context = array(
'http' => array(
'request_fulluri' => true,
'timeout' => $connection_timeout,
)
);
$context = Util::handleContext($context);
$response = file_get_contents(
$file,
false,
stream_context_create($context)
);
}
}

View File

@ -292,7 +292,6 @@ $goto_whitelist = array(
'index.php',
'pdf_pages.php',
'pdf_schema.php',
//'phpinfo.php',
'server_binlog.php',
'server_collations.php',
'server_databases.php',

View File

@ -1038,13 +1038,6 @@ $cfg['NavigationTreeShowEvents'] = true;
*/
$cfg['ShowStats'] = true;
/**
* show PHP info link
*
* @global boolean $cfg['ShowPhpInfo']
*/
$cfg['ShowPhpInfo'] = false;
/**
* show MySQL server and web server information
*

View File

@ -216,10 +216,22 @@ class ServerConfigChecks
$blowfishSecret, $cookieAuthServer, $blowfishSecretSet
) {
if ($cookieAuthServer && $blowfishSecret === null) {
$blowfishSecret = uniqid('', true);
$blowfishSecret = '';
if (! function_exists('openssl_random_pseudo_bytes')) {
$random_func = 'phpseclib\\Crypt\\Random::string';
} else {
$random_func = 'openssl_random_pseudo_bytes';
}
while (strlen($blowfishSecret) < 32) {
$byte = $random_func(1);
// We want only ASCII chars
if (ord($byte) > 32 && ord($byte) < 127) {
$blowfishSecret .= $byte;
}
}
$blowfishSecretSet = true;
$this->cfg->set('blowfish_secret', $blowfishSecret);
return array($blowfishSecret, $blowfishSecretSet);
}
return array($blowfishSecret, $blowfishSecretSet);
}
@ -331,10 +343,10 @@ class ServerConfigChecks
} else {
$blowfishWarnings = array();
// check length
if (mb_strlen($blowfishSecret) < 8) {
if (strlen($blowfishSecret) < 32) {
// too short key
$blowfishWarnings[] = __(
'Key is too short, it should have at least 8 characters.'
'Key is too short, it should have at least 32 characters.'
);
}
// check used characters

View File

@ -183,6 +183,7 @@ class Validator
) {
// static::testPHPErrorMsg();
$error = null;
$host = PMA_sanitizeMySQLHost($host);
if (DatabaseInterface::checkDbExtension('mysqli')) {
$socket = empty($socket) || $connect_type == 'tcp' ? null : $socket;

View File

@ -871,11 +871,6 @@ $strConfigShowFunctionFields_desc = __(
$strConfigShowFunctionFields_name = __('Show function fields');
$strConfigShowHint_desc = __('Whether to show hint or not.');
$strConfigShowHint_name = __('Show hint');
$strConfigShowPhpInfo_desc = __(
'Shows link to [a@https://php.net/manual/function.phpinfo.php]phpinfo()[/a] ' .
'output.'
);
$strConfigShowPhpInfo_name = __('Show phpinfo() link');
$strConfigShowServerInfo_name = __('Show detailed MySQL server information');
$strConfigShowSQL_desc = __(
'Defines whether SQL queries generated by phpMyAdmin should be displayed.'

View File

@ -204,7 +204,6 @@ $forms['Main_panel']['Startup'] = array(
'ShowCreateDb',
'ShowStats',
'ShowServerInfo',
'ShowPhpInfo',
'ShowChgPassword');
$forms['Main_panel']['DbStructure'] = array(
'ShowDbStructureCharset',

View File

@ -501,11 +501,6 @@ function PMA_sendHeaderLocation($uri, $use_refresh = false)
session_write_close();
if ($response->headersSent()) {
if (function_exists('debug_print_backtrace')) {
echo '<pre>';
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
echo '</pre>';
}
trigger_error(
'PMA_sendHeaderLocation called when headers are already sent!',
E_USER_ERROR
@ -735,6 +730,10 @@ 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'])) {
return false;
}
$domain = $arr["host"];
$domainWhiteList = array(
/* Include current domain */
@ -953,6 +952,50 @@ function PMA_checkExtensions()
}
}
/**
* Gets the "true" IP address of the current user
*
* @return string the ip of the user
*
* @access private
*/
function PMA_getIp()
{
/* Get the address of user */
if (empty($_SERVER['REMOTE_ADDR'])) {
/* We do not know remote IP */
return false;
}
$direct_ip = $_SERVER['REMOTE_ADDR'];
/* Do we trust this IP as a proxy? If yes we will use it's header. */
if (!isset($GLOBALS['cfg']['TrustedProxies'][$direct_ip])) {
/* Return true IP */
return $direct_ip;
}
/**
* Parse header in form:
* X-Forwarded-For: client, proxy1, proxy2
*/
// Get header content
$value = PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
// Grab first element what is client adddress
$value = explode(',', $value)[0];
// checks that the header contains only one IP address,
$is_ip = filter_var($value, FILTER_VALIDATE_IP);
if ($is_ip !== false) {
// True IP behind a proxy
return $value;
}
// We could not parse header
return false;
} // end of the 'PMA_getIp()' function
/* Compatibility with PHP < 5.6 */
if(! function_exists('hash_equals')) {
@ -970,3 +1013,135 @@ if(! function_exists('hash_equals')) {
return ! $ret;
}
}
/* Compatibility with PHP < 5.1 or PHP without hash extension */
if (! function_exists('hash_hmac')) {
function hash_hmac($algo, $data, $key, $raw_output = false)
{
$algo = strtolower($algo);
$pack = 'H'.strlen($algo('test'));
$size = 64;
$opad = str_repeat(chr(0x5C), $size);
$ipad = str_repeat(chr(0x36), $size);
if (strlen($key) > $size) {
$key = str_pad(pack($pack, $algo($key)), $size, chr(0x00));
} else {
$key = str_pad($key, $size, chr(0x00));
}
for ($i = 0; $i < strlen($key) - 1; $i++) {
$opad[$i] = $opad[$i] ^ $key[$i];
$ipad[$i] = $ipad[$i] ^ $key[$i];
}
$output = $algo($opad.pack($pack, $algo($ipad.$data)));
return ($raw_output) ? pack($pack, $output) : $output;
}
}
/**
* Sanitizes MySQL hostname
*
* * strips p: prefix
*
* @param string $name User given hostname
*
* @return string
*/
function PMA_sanitizeMySQLHost($name)
{
if (strtolower(substr($name, 0, 2)) == 'p:') {
return substr($name, 2);
}
return $name;
}
/**
* Safe unserializer wrapper
*
* It does not unserialize data containing objects
*
* @param string $data Data to unserialize
*
* @return mixed
*/
function PMA_safeUnserialize($data)
{
if (! is_string($data)) {
return null;
}
/* validate serialized data */
$length = strlen($data);
$depth = 0;
for ($i = 0; $i < $length; $i++) {
$value = $data[$i];
switch ($value)
{
case '}':
/* end of array */
if ($depth <= 0) {
return null;
}
$depth--;
break;
case 's':
/* string */
// parse sting length
$strlen = intval($data[$i + 2]);
// string start
$i = strpos($data, ':', $i + 2);
if ($i === false) {
return null;
}
// skip string, quotes and ;
$i += 2 + $strlen + 1;
if ($data[$i] != ';') {
return null;
}
break;
case 'b':
case 'i':
case 'd':
/* bool, integer or double */
// skip value to sepearator
$i = strpos($data, ';', $i);
if ($i === false) {
return null;
}
break;
case 'a':
/* array */
// find array start
$i = strpos($data, '{', $i);
if ($i === false) {
return null;
}
// remember nesting
$depth++;
break;
case 'N':
/* null */
// skip to end
$i = strpos($data, ';', $i);
if ($i === false) {
return null;
}
break;
default:
/* any other elements are not wanted */
return null;
}
}
// check unterminated arrays
if ($depth > 0) {
return null;
}
return unserialize($data);
}

View File

@ -446,18 +446,19 @@ function PMA_getTableCreationQuery($db, $table)
function PMA_getNumberOfFieldsFromRequest()
{
if (isset($_REQUEST['submit_num_fields'])) { // adding new fields
$num_fields = $_REQUEST['orig_num_fields'] + $_REQUEST['added_fields'];
$num_fields = intval($_REQUEST['orig_num_fields']) + intval($_REQUEST['added_fields']);
} elseif (isset($_REQUEST['orig_num_fields'])) { // retaining existing fields
$num_fields = $_REQUEST['orig_num_fields'];
$num_fields = intval($_REQUEST['orig_num_fields']);
} elseif (isset($_REQUEST['num_fields'])
&& intval($_REQUEST['num_fields']) > 0
) { // new table with specified number of fields
$num_fields = (int) $_REQUEST['num_fields'];
$num_fields = intval($_REQUEST['num_fields']);
} else { // new table with unspecified number of fields
$num_fields = 4;
}
return $num_fields;
// Limit to 4096 fields (MySQL maximal value)
return min($num_fields, 4096);
}
/**

View File

@ -90,7 +90,7 @@ function PMA_getPageIdsAndNames($db)
$result = array();
while ($curr_page = $GLOBALS['dbi']->fetchAssoc($page_rs)) {
$result[$curr_page['page_nr']] = $curr_page['page_descr'];
$result[intval($curr_page['page_nr'])] = $curr_page['page_descr'];
}
return $result;
}

View File

@ -115,10 +115,12 @@ class DBIMysql implements DBIExtension
$client_flags = 0;
// always use CLIENT_LOCAL_FILES as defined in mysql_com.h
// for the case where the client library was not compiled
// with --enable-local-infile
$client_flags |= 128;
if (defined('PMA_ENABLE_LDI')) {
// use CLIENT_LOCAL_FILES as defined in mysql_com.h
// for the case where the client library was not compiled
// with --enable-local-infile
$client_flags |= 128;
}
/* Optionally compress connection */
if (defined('MYSQL_CLIENT_COMPRESS') && $server['compress']) {

View File

@ -129,7 +129,11 @@ class DBIMysqli implements DBIExtension
$link = mysqli_init();
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
if (defined('PMA_ENABLE_LDI')) {
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
} else {
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, false);
}
$client_flags = 0;

View File

@ -252,7 +252,7 @@ function PMA_getOptionsForExportTemplates($export_type)
. PMA\libraries\Util::backquote($cfgRelation['export_templates'])
. " WHERE `username` = "
. "'" . PMA\libraries\Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user'])
. "' AND `export_type` = '" . $export_type . "'"
. "' AND `export_type` = '" . PMA\libraries\Util::sqlAddSlashes($export_type) . "'"
. " ORDER BY `template_name`;";
$result = PMA_queryAsControlUser($query);

View File

@ -37,7 +37,7 @@ function PMA_printGitRevision()
'https://github.com/phpmyadmin/phpmyadmin/commit/'
. $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_COMMITHASH')
)
. '" target="_blank">' . $commit_hash . '</a>';
. '" rel="noopener noreferrer" target="_blank">' . $commit_hash . '</a>';
}
$branch = $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_BRANCH');
@ -47,7 +47,7 @@ function PMA_printGitRevision()
'https://github.com/phpmyadmin/phpmyadmin/tree/'
. $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_BRANCH')
)
. '" target="_blank">' . $branch . '</a>';
. '" rel="noopener noreferrer" target="_blank">' . $branch . '</a>';
}
if ($branch !== false) {
$branch = sprintf(__('%1$s from %2$s branch'), $commit_hash, $branch);

View File

@ -182,7 +182,7 @@ class Pbxt extends StorageEngine
. ' can be found on the %sPrimeBase XT Home Page%s.'
),
'<a href="' . PMA_linkURL('https://mariadb.com/kb/en/mariadb/about-pbxt/')
. '" target="_blank">',
. '" rel="noopener noreferrer" target="_blank">',
'</a>'
)
. '</p>' . "\n";

View File

@ -179,7 +179,24 @@ function PMA_sanitizeUrl($url)
function PMA_sendErrorReport($report)
{
$data_string = json_encode($report);
if (ini_get('allow_url_fopen')) {
if (function_exists('curl_init')) {
$curl_handle = curl_init(SUBMISSION_URL);
if ($curl_handle === false) {
return null;
}
$curl_handle = PMA\libraries\Util::configureCurl($curl_handle);
curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt(
$curl_handle, CURLOPT_HTTPHEADER,
array('Expect:', 'Content-Type: application/json')
);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($curl_handle);
curl_close($curl_handle);
return $response;
} else if (ini_get('allow_url_fopen')) {
$context = array("http" =>
array(
'method' => 'POST',
@ -196,26 +213,7 @@ function PMA_sendErrorReport($report)
return $response;
}
if (!function_exists('curl_init')) {
return null;
}
$curl_handle = curl_init(SUBMISSION_URL);
if ($curl_handle === false) {
return null;
}
$curl_handle = PMA\libraries\Util::configureCurl($curl_handle);
curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt(
$curl_handle, CURLOPT_HTTPHEADER,
array('Expect:', 'Content-Type: application/json')
);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($curl_handle);
curl_close($curl_handle);
return $response;
return null;
}
/**

View File

@ -26,6 +26,7 @@ function PMA_getDirContent($dir, $expression = '')
}
while ($file = @readdir($handle)) {
if (@is_file($dir . $file)
&& ! @is_link($dir . $file)
&& ($expression == '' || preg_match($expression, $file))
) {
$result[] = $file;

View File

@ -129,11 +129,11 @@ abstract class GISGeometry
. 'bound.extend(new OpenLayers.LonLat('
. $scale_data['minX'] . ', ' . $scale_data['minY']
. ').transform(new OpenLayers.Projection("EPSG:'
. $srid . '"), map.getProjectionObject())); '
. intval($srid) . '"), map.getProjectionObject())); '
. 'bound.extend(new OpenLayers.LonLat('
. $scale_data['maxX'] . ', ' . $scale_data['maxY']
. ').transform(new OpenLayers.Projection("EPSG:'
. $srid . '"), map.getProjectionObject()));';
. intval($srid) . '"), map.getProjectionObject()));';
}
/**
@ -222,7 +222,7 @@ abstract class GISGeometry
// Extract coordinates of the point
$cordinates = explode(" ", $point);
if (isset($cordinates[0]) && trim($cordinates[0]) != ''
if (!empty($cordinates[0]) && trim($cordinates[0]) != ''
&& isset($cordinates[1])
&& trim($cordinates[1]) != ''
) {
@ -231,8 +231,8 @@ abstract class GISGeometry
$y = $scale_data['height']
- ($cordinates[1] - $scale_data['y']) * $scale_data['scale'];
} else {
$x = trim($cordinates[0]);
$y = trim($cordinates[1]);
$x = floatval(trim($cordinates[0]));
$y = floatval(trim($cordinates[1]));
}
} else {
$x = '';
@ -394,6 +394,6 @@ abstract class GISGeometry
{
return '(new OpenLayers.Geometry.Point(' . $point[0] . ',' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:'
. $srid . '"), map.getProjectionObject())';
. intval($srid) . '"), map.getProjectionObject())';
}
}

View File

@ -7,45 +7,6 @@
* @package PhpMyAdmin
*/
/**
* Gets the "true" IP address of the current user
*
* @return string the ip of the user
*
* @access private
*/
function PMA_getIp()
{
/* Get the address of user */
if (empty($_SERVER['REMOTE_ADDR'])) {
/* We do not know remote IP */
return false;
}
$direct_ip = $_SERVER['REMOTE_ADDR'];
/* Do we trust this IP as a proxy? If yes we will use it's header. */
if (!isset($GLOBALS['cfg']['TrustedProxies'][$direct_ip])) {
/* Return true IP */
return $direct_ip;
}
$trusted_header_value
= PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
$matches = array();
// checks that the header contains only one IP address,
$is_ip = filter_var($trusted_header_value, FILTER_VALIDATE_IP);
if ($is_ip !== false) {
// True IP behind a proxy
return $trusted_header_value;
}
/* Return true IP */
return $direct_ip;
} // end of the 'PMA_getIp()' function
/**
* Matches for IPv4 or IPv6 addresses
*

View File

@ -175,7 +175,7 @@ class NavigationTree
$query = "SELECT (COUNT(DB_first_level) DIV %d) * %d ";
$query .= "from ( ";
$query .= " SELECT distinct SUBSTRING_INDEX(SCHEMA_NAME, ";
$query .= " '{$GLOBALS['cfg']['NavigationTreeDbSeparator']}', 1) ";
$query .= " '" . Util::sqlAddSlashes($GLOBALS['cfg']['NavigationTreeDbSeparator']) . "', 1) ";
$query .= " DB_first_level ";
$query .= " FROM INFORMATION_SCHEMA.SCHEMATA ";
$query .= " WHERE `SCHEMA_NAME` < '%s' ";

View File

@ -434,7 +434,7 @@ class Node
$query .= "SELECT DB_first_level ";
$query .= "FROM ( ";
$query .= "SELECT DISTINCT SUBSTRING_INDEX(SCHEMA_NAME, ";
$query .= "'$dbSeparator', 1) ";
$query .= "'" . Util::sqlAddSlashes($dbSeparator) . "', 1) ";
$query .= "DB_first_level ";
$query .= "FROM INFORMATION_SCHEMA.SCHEMATA ";
$query .= $this->_getWhereClause('SCHEMA_NAME', $searchClause);
@ -444,9 +444,9 @@ class Node
$query .= ") t2 ";
$query .= $this->_getWhereClause('SCHEMA_NAME', $searchClause);
$query .= "AND 1 = LOCATE(CONCAT(DB_first_level, ";
$query .= "'$dbSeparator'), ";
$query .= "'" . Util::sqlAddSlashes($dbSeparator) . "'), ";
$query .= "CONCAT(SCHEMA_NAME, ";
$query .= "'$dbSeparator')) ";
$query .= "'" . Util::sqlAddSlashes($dbSeparator) . "')) ";
$query .= "ORDER BY SCHEMA_NAME ASC";
$retval = $GLOBALS['dbi']->fetchResult($query);

View File

@ -691,7 +691,7 @@ class NodeDatabase extends Node
. '<a href="navigation.php'
. URL::getCommon()
. '&showUnhideDialog=true'
. '&dbName=' . urldecode($this->real_name) . '"'
. '&dbName=' . urlencode($this->real_name) . '"'
. ' class="showUnhide ajax">'
. Util::getImage(
'show.png',

View File

@ -37,7 +37,10 @@ function PMA_getPlugin(
if (is_file($plugins_dir . $file)) {
//include_once $plugins_dir . $file;
$fqnClass = 'PMA\\' . str_replace('/', '\\', $plugins_dir) . $class_name;
return new $fqnClass;
// check if class exists, could be caused by skip_import
if (class_exists($fqnClass)) {
return new $fqnClass;
}
}
return null;

View File

@ -286,7 +286,7 @@ class AuthenticationCookie extends AuthenticationPlugin
// verify captcha status.
$resp = $reCaptcha->verify(
$_POST["g-recaptcha-response"],
$_SERVER["REMOTE_ADDR"]
PMA_getIp()
);
// Check if the captcha entered is valid, if not stop the login.
@ -324,7 +324,7 @@ class AuthenticationCookie extends AuthenticationPlugin
return false;
}
}
$GLOBALS['pma_auth_server'] = $_REQUEST['pma_servername'];
$GLOBALS['pma_auth_server'] = PMA_sanitizeMySQLHost($_REQUEST['pma_servername']);
}
PMA_secureSession();
return true;
@ -333,18 +333,8 @@ class AuthenticationCookie extends AuthenticationPlugin
// At the end, try to set the $GLOBALS['PHP_AUTH_USER']
// and $GLOBALS['PHP_AUTH_PW'] variables from cookies
// servername
if ($GLOBALS['cfg']['AllowArbitraryServer']
&& ! empty($_COOKIE['pmaServer-' . $GLOBALS['server']])
) {
$GLOBALS['pma_auth_server']
= $_COOKIE['pmaServer-' . $GLOBALS['server']];
}
// check cookies
if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])
|| empty($_COOKIE['pma_iv-' . $GLOBALS['server']])
) {
if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) {
return false;
}
@ -381,15 +371,26 @@ class AuthenticationCookie extends AuthenticationPlugin
}
// check password cookie
if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
if (empty($_COOKIE['pmaAuth-' . $GLOBALS['server']])) {
return false;
}
$GLOBALS['PHP_AUTH_PW'] = $this->cookieDecrypt(
$_COOKIE['pmaPass-' . $GLOBALS['server']],
$this->_getSessionEncryptionSecret()
$auth_data = json_decode(
$this->cookieDecrypt(
$_COOKIE['pmaAuth-' . $GLOBALS['server']],
$this->_getSessionEncryptionSecret()
),
true
);
if (! is_array($auth_data) || ! isset($auth_data['password'])) {
return false;
}
$GLOBALS['PHP_AUTH_PW'] = $auth_data['password'];
if ($GLOBALS['cfg']['AllowArbitraryServer'] && ! empty($auth_data['server'])) {
$GLOBALS['pma_auth_server'] = $auth_data['server'];
}
$GLOBALS['from_cookie'] = true;
return true;
@ -464,8 +465,6 @@ class AuthenticationCookie extends AuthenticationPlugin
{
global $cfg;
$this->createIV();
// Name and password cookies need to be refreshed each time
// Duration = one month for username
$this->storeUsernameCookie($cfg['Server']['user']);
@ -480,21 +479,6 @@ class AuthenticationCookie extends AuthenticationPlugin
// Set server cookies if required (once per session) and, in this case,
// force reload to ensure the client accepts cookies
if (! $GLOBALS['from_cookie']) {
if ($GLOBALS['cfg']['AllowArbitraryServer']) {
if (! empty($GLOBALS['pma_auth_server'])) {
// Duration = one month for servername
$GLOBALS['PMA_Config']->setCookie(
'pmaServer-' . $GLOBALS['server'],
$cfg['Server']['host']
);
} else {
// Delete servername cookie
$GLOBALS['PMA_Config']->removeCookie(
'pmaServer-' . $GLOBALS['server']
);
}
}
// URL where to go:
$redirect_url = './index.php';
@ -564,11 +548,15 @@ class AuthenticationCookie extends AuthenticationPlugin
*/
public function storePasswordCookie($password)
{
$payload = array('password' => $password);
if ($GLOBALS['cfg']['AllowArbitraryServer'] && ! empty($GLOBALS['pma_auth_server'])) {
$payload['server'] = $GLOBALS['pma_auth_server'];
}
// Duration = as configured
$GLOBALS['PMA_Config']->setCookie(
'pmaPass-' . $GLOBALS['server'],
'pmaAuth-' . $GLOBALS['server'],
$this->cookieEncrypt(
$password,
json_encode($payload),
$this->_getSessionEncryptionSecret()
),
null,
@ -592,7 +580,7 @@ class AuthenticationCookie extends AuthenticationPlugin
global $conn_error;
// Deletes password cookie and displays the login form
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']);
$GLOBALS['PMA_Config']->removeCookie('pmaAuth-' . $GLOBALS['server']);
$conn_error = $this->getErrorMessage();
@ -615,8 +603,7 @@ class AuthenticationCookie extends AuthenticationPlugin
if (empty($GLOBALS['cfg']['blowfish_secret'])) {
return $this->_getSessionEncryptionSecret();
} else {
// apply md5() to work around too long secrets (returns 32 characters)
return md5($GLOBALS['cfg']['blowfish_secret']);
return $GLOBALS['cfg']['blowfish_secret'];
}
}
@ -629,9 +616,9 @@ class AuthenticationCookie extends AuthenticationPlugin
{
if (empty($_SESSION['encryption_key'])) {
if (self::useOpenSSL()) {
$_SESSION['encryption_key'] = openssl_random_pseudo_bytes(256);
$_SESSION['encryption_key'] = openssl_random_pseudo_bytes(32);
} else {
$_SESSION['encryption_key'] = Crypt\Random::string(256);
$_SESSION['encryption_key'] = Crypt\Random::string(32);
}
}
return $_SESSION['encryption_key'];
@ -647,6 +634,64 @@ class AuthenticationCookie extends AuthenticationPlugin
return ! class_exists('phpseclib\Crypt\Random');
}
/**
* Concatenates secret in order to make it 16 bytes log
*
* This doesn't add any security, just ensures the secret
* is long enough by copying it.
*
* @param string $secret Original secret
*
* @return string
*/
public function enlargeSecret($secret)
{
while (strlen($secret) < 16) {
$secret .= $secret;
}
return substr($secret, 0, 16);
}
/**
* Derives MAC secret from encryption secret.
*
* @param string $secret the secret
*
* @return string the MAC secret
*/
public function getMACSecret($secret)
{
// Grab first part, up to 16 chars
// The MAC and AES secrets can overlap if original secret is short
$length = strlen($secret);
if ($length > 16) {
return substr($secret, 0, 16);
}
return $this->enlargeSecret(
$length == 1 ? $secret : substr($secret, 0, -1)
);
}
/**
* Derives AES secret from encryption secret.
*
* @param string $secret the secret
*
* @return string the AES secret
*/
public function getAESSecret($secret)
{
// Grab second part, up to 16 chars
// The MAC and AES secrets can overlap if original secret is short
$length = strlen($secret);
if ($length > 16) {
return substr($secret, -16);
}
return $this->enlargeSecret(
$length == 1 ? $secret : substr($secret, 1)
);
}
/**
* Encryption using openssl's AES or phpseclib's AES
* (phpseclib uses mcrypt when it is available)
@ -658,20 +703,31 @@ class AuthenticationCookie extends AuthenticationPlugin
*/
public function cookieEncrypt($data, $secret)
{
$mac_secret = $this->getMACSecret($secret);
$aes_secret = $this->getAESSecret($secret);
$iv = $this->createIV();
if (self::useOpenSSL()) {
return openssl_encrypt(
$result = openssl_encrypt(
$data,
'AES-128-CBC',
$secret,
0,
$this->_cookie_iv
$iv
);
} else {
$cipher = new Crypt\AES(Crypt\Base::MODE_CBC);
$cipher->setIV($this->_cookie_iv);
$cipher->setKey($secret);
return base64_encode($cipher->encrypt($data));
$cipher->setIV($iv);
$cipher->setKey($aes_secret);
$result = base64_encode($cipher->encrypt($data));
}
$iv = base64_encode($iv);
return json_encode(
array(
'iv' => $iv,
'mac' => hash_hmac('sha1', $iv . $result, $mac_secret),
'payload' => $result,
)
);
}
/**
@ -681,33 +737,39 @@ class AuthenticationCookie extends AuthenticationPlugin
* @param string $encdata encrypted data
* @param string $secret the secret
*
* @return string original data
* @return string|bool original data, false on error
*/
public function cookieDecrypt($encdata, $secret)
{
if (is_null($this->_cookie_iv)) {
$this->_cookie_iv = base64_decode(
$_COOKIE['pma_iv-' . $GLOBALS['server']],
true
);
$data = json_decode($encdata, true);
if (! is_array($data) || ! isset($data['mac']) || ! isset($data['iv']) || ! isset($data['payload'])
|| ! is_string($data['mac']) || ! is_string($data['iv']) || ! is_string($data['payload'])
) {
return false;
}
if (strlen($this->_cookie_iv) < $this->getIVSize()) {
$this->createIV();
$mac_secret = $this->getMACSecret($secret);
$aes_secret = $this->getAESSecret($secret);
$newmac = hash_hmac('sha1', $data['iv'] . $data['payload'], $mac_secret);
if (! hash_equals($data['mac'], $newmac)) {
return false;
}
if (self::useOpenSSL()) {
return openssl_decrypt(
$encdata,
$data['payload'],
'AES-128-CBC',
$secret,
0,
$this->_cookie_iv
base64_decode($data['iv'])
);
} else {
$cipher = new Crypt\AES(Crypt\Base::MODE_CBC);
$cipher->setIV($this->_cookie_iv);
$cipher->setKey($secret);
return $cipher->decrypt(base64_decode($encdata));
$cipher->setIV(base64_decode($data['iv']));
$cipher->setKey($aes_secret);
return $cipher->decrypt(base64_decode($data['payload']));
}
}
@ -735,24 +797,26 @@ class AuthenticationCookie extends AuthenticationPlugin
*/
public function createIV()
{
/* Testsuite shortcut only to allow predictable IV */
if (! is_null($this->_cookie_iv)) {
return $this->_cookie_iv;
}
if (self::useOpenSSL()) {
$this->_cookie_iv = openssl_random_pseudo_bytes(
return openssl_random_pseudo_bytes(
$this->getIVSize()
);
} else {
$this->_cookie_iv = Crypt\Random::string(
return Crypt\Random::string(
$this->getIVSize()
);
}
$GLOBALS['PMA_Config']->setCookie(
'pma_iv-' . $GLOBALS['server'],
base64_encode($this->_cookie_iv)
);
}
/**
* Sets encryption IV to use
*
* This is for testing only!
*
* @param string $vector The IV
*
* @return void
@ -784,17 +848,17 @@ class AuthenticationCookie extends AuthenticationPlugin
// -> delete password cookie(s)
if ($GLOBALS['cfg']['LoginCookieDeleteAll']) {
foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
if (isset($_COOKIE['pmaPass-' . $key])) {
unset($_COOKIE['pmaPass-' . $key]);
$GLOBALS['PMA_Config']->removeCookie('pmaAuth-' . $key);
if (isset($_COOKIE['pmaAuth-' . $key])) {
unset($_COOKIE['pmaAuth-' . $key]);
}
}
} else {
$GLOBALS['PMA_Config']->removeCookie(
'pmaPass-' . $GLOBALS['server']
'pmaAuth-' . $GLOBALS['server']
);
if (isset($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
unset($_COOKIE['pmaPass-' . $GLOBALS['server']]);
if (isset($_COOKIE['pmaAuth-' . $GLOBALS['server']])) {
unset($_COOKIE['pmaAuth-' . $GLOBALS['server']]);
}
}
parent::logOut();

View File

@ -360,7 +360,7 @@ class ExportMediawiki extends ExportPlugin
// see https://www.mediawiki.org/wiki/Help:Formatting
$comment = $this->_exportCRLF();
$comment .= '<!--' . $this->_exportCRLF();
$comment .= $text . $this->_exportCRLF();
$comment .= htmlspecialchars($text) . $this->_exportCRLF();
$comment .= '-->' . str_repeat($this->_exportCRLF(), 2);
return $comment;

View File

@ -65,6 +65,19 @@ class ExportPhparray extends ExportPlugin
$this->properties = $exportPluginProperties;
}
/**
* Removes end of comment from a string
*
* @param string $string String to replace
*
* @return string
*/
public function commentString($string)
{
return strtr($string, '*/', '-');
}
/**
* Outputs export header
*
@ -76,7 +89,7 @@ class ExportPhparray extends ExportPlugin
'<?php' . $GLOBALS['crlf']
. '/**' . $GLOBALS['crlf']
. ' * Export to PHP Array plugin for PHPMyAdmin' . $GLOBALS['crlf']
. ' * @version 0.2b' . $GLOBALS['crlf']
. ' * @version ' . PMA_VERSION . $GLOBALS['crlf']
. ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf']
);
@ -107,9 +120,9 @@ class ExportPhparray extends ExportPlugin
$db_alias = $db;
}
PMA_exportOutputHandler(
'//' . $GLOBALS['crlf']
. '// Database ' . PMA\libraries\Util::backquote($db_alias)
. $GLOBALS['crlf'] . '//' . $GLOBALS['crlf']
'/**' . $GLOBALS['crlf']
. ' * Database ' . $this->commentString(PMA\libraries\Util::backquote($db_alias))
. $GLOBALS['crlf'] . ' */' . $GLOBALS['crlf']
);
return true;
@ -207,9 +220,9 @@ class ExportPhparray extends ExportPlugin
$buffer = '';
$record_cnt = 0;
// Output table name as comment
$buffer .= $crlf . '// '
. PMA\libraries\Util::backquote($db_alias) . '.'
. PMA\libraries\Util::backquote($table_alias) . $crlf;
$buffer .= $crlf . '/* '
. $this->commentString(PMA\libraries\Util::backquote($db_alias)) . '.'
. $this->commentString(PMA\libraries\Util::backquote($table_alias)) . ' */' . $crlf;
$buffer .= '$' . $tablefixed . ' = array(';
while ($record = $GLOBALS['dbi']->fetchRow($result)) {

View File

@ -596,7 +596,16 @@ class ExportSql extends ExportPlugin
&& $GLOBALS['sql_include_comments']
) {
// see https://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html
return '--' . (empty($text) ? '' : ' ') . $text . $GLOBALS['crlf'];
if (empty($text)) {
return '--' . $GLOBALS['crlf'];
} else {
$lines = preg_split("/\\r\\n|\\r|\\n/", $text);
$result = array();
foreach ($lines as $line) {
$result[] = '-- ' . $line . $GLOBALS['crlf'];
}
return implode('', $result);
}
} else {
return '';
}
@ -1112,7 +1121,7 @@ class ExportSql extends ExportPlugin
$dbNameColumn
)
. " = '" . Util::sqlAddSlashes($db) . "'"
. " AND `page_nr` = '" . $page . "'";
. " AND `page_nr` = '" . intval($page) . "'";
if (!$this->exportData(
$cfgRelation['db'],

View File

@ -185,7 +185,7 @@ class ExportXml extends ExportPlugin
if ($names) {
foreach ($names as $name) {
$head .= ' <pma:' . $type . ' name="'
. $name . '">' . $crlf;
. htmlspecialchars($name) . '">' . $crlf;
// Do some formatting
$sql = $GLOBALS['dbi']->getDefinition($db, $dbitype, $name);
@ -232,7 +232,7 @@ class ExportXml extends ExportPlugin
. '- version ' . PMA_VERSION . $crlf
. '- https://www.phpmyadmin.net' . $crlf
. '-' . $crlf
. '- ' . __('Host:') . ' ' . $cfg['Server']['host'];
. '- ' . __('Host:') . ' ' . htmlspecialchars($cfg['Server']['host']);
if (!empty($cfg['Server']['port'])) {
$head .= ':' . $cfg['Server']['port'];
}
@ -263,7 +263,7 @@ class ExportXml extends ExportPlugin
$head .= ' -->' . $crlf;
$head .= ' <pma:structure_schemas>' . $crlf;
$head .= ' <pma:database name="' . htmlspecialchars($db)
. '" collation="' . $db_collation . '" charset="' . $db_charset
. '" collation="' . htmlspecialchars($db_collation) . '" charset="' . htmlspecialchars($db_charset)
. '">' . $crlf;
if (count($tables) == 0) {
@ -296,7 +296,7 @@ class ExportXml extends ExportPlugin
continue;
}
$head .= ' <pma:' . $type . ' name="' . $table . '">'
$head .= ' <pma:' . $type . ' name="' . htmlspecialchars($table) . '">'
. $crlf;
$tbl = " " . htmlspecialchars($tbl);
@ -314,7 +314,7 @@ class ExportXml extends ExportPlugin
foreach ($triggers as $trigger) {
$code = $trigger['create'];
$head .= ' <pma:trigger name="'
. $trigger['name'] . '">' . $crlf;
. htmlspecialchars($trigger['name']) . '">' . $crlf;
// Do some formatting
$code = mb_substr(rtrim($code), 0, -3);
@ -402,7 +402,7 @@ class ExportXml extends ExportPlugin
) {
$head = ' <!--' . $crlf
. ' - ' . __('Database:') . ' ' . '\''
. $db_alias . '\'' . $crlf
. htmlspecialchars($db_alias) . '\'' . $crlf
. ' -->' . $crlf . ' <database name="'
. htmlspecialchars($db_alias) . '">' . $crlf;
@ -491,7 +491,7 @@ class ExportXml extends ExportPlugin
unset($i);
$buffer = ' <!-- ' . __('Table') . ' '
. $table_alias . ' -->' . $crlf;
. htmlspecialchars($table_alias) . ' -->' . $crlf;
if (!PMA_exportOutputHandler($buffer)) {
return false;
}

View File

@ -100,21 +100,24 @@ class ImportShp extends ImportPlugin
// Extract the .dbf file and point to it.
$extracted = PMA_zipExtract(
$import_file,
realpath($GLOBALS['cfg']['TempDir']),
array($dbf_file_name)
$dbf_file_name
);
if ($extracted) {
if ($extracted !== false) {
$dbf_file_path = realpath($GLOBALS['cfg']['TempDir'])
. (PMA_IS_WINDOWS ? '\\' : '/') . $dbf_file_name;
$temp_dbf_file = true;
// Replace the .dbf with .*, as required
// by the bsShapeFiles library.
$file_name = mb_substr(
$dbf_file_path,
0,
mb_strlen($dbf_file_path) - 4
) . '.*';
$shp->FileName = $file_name;
. (PMA_IS_WINDOWS ? '\\' : '/')
. PMA_sanitizeFilename($dbf_file_name, true);
$handle = fopen($dbf_file_path, 'wb');
if ($handle !== false) {
fwrite($handle, $extracted);
fclose($handle);
$temp_dbf_file = true;
// Replace the .dbf with .*, as required
// by the bsShapeFiles library.
$file_name = substr(
$dbf_file_path, 0, strlen($dbf_file_path) - 4
) . '.*';
$shp->FileName = $file_name;
}
}
}
} elseif (!empty($local_import_file)
@ -134,6 +137,14 @@ class ImportShp extends ImportPlugin
}
}
// Delete the .dbf file extracted to 'TempDir'
if ($temp_dbf_file
&& isset($dbf_file_path)
&& file_exists($dbf_file_path)
) {
unlink($dbf_file_path);
}
// Load data
$shp->loadFromFile('');
if ($shp->lastError != "") {
@ -146,14 +157,6 @@ class ImportShp extends ImportPlugin
return;
}
// Delete the .dbf file extracted to 'TempDir'
if ($temp_dbf_file
&& isset($dbf_file_path)
&& file_exists($dbf_file_path)
) {
unlink($dbf_file_path);
}
switch ($shp->shapeType) {
// ESRI Null Shape
case 0:

View File

@ -54,7 +54,7 @@ class ExportRelationSchema
*/
public function setPageNumber($value)
{
$this->pageNumber = $value;
$this->pageNumber = intval($value);
}
/**

View File

@ -42,7 +42,9 @@ abstract class FormattedTransformationsPlugin extends TransformationsPlugin
*/
public function applyTransformation($buffer, $options = array(), $meta = '')
{
return $buffer;
return '<iframe srcdoc="'
. strtr($buffer, '"', '\'')
. '" sandbox=""></iframe>';
}

View File

@ -49,7 +49,7 @@ abstract class ImageLinkTransformationsPlugin extends TransformationsPlugin
{
// must disable the page loader, see
// https://wiki.phpmyadmin.net/pma/Page_loader#Bypassing_the_page_loader
return '<a class="disableAjax" target="_new" href="transformation_wrapper.php'
return '<a class="disableAjax" target="_blank" rel="noopener noreferrer" href="transformation_wrapper.php'
. $options['wrapper_link'] . '" alt="[' . htmlspecialchars($buffer) . ']">[BLOB]</a>';
}

View File

@ -82,8 +82,8 @@ abstract class ImageUploadTransformationsPlugin extends IOTransformationsPlugin
$src = 'transformation_wrapper.php' . $options['wrapper_link'];
}
$html .= '<img src="' . $src . '" width="'
. (isset($options[0]) ? $options[0] : '100') . '" height="'
. (isset($options[1]) ? $options[1] : '100') . '" alt="'
. (isset($options[0]) ? intval($options[0]) : '100') . '" height="'
. (isset($options[1]) ? intval($options[1]) : '100') . '" alt="'
. __('Image preview here') . '"/>';
$html .= '<br/><input type="file" name="fields_upload'
. $column_name_appendix . '" accept="image/*" class="image-upload"/>';

View File

@ -51,10 +51,10 @@ abstract class InlineTransformationsPlugin extends TransformationsPlugin
if (PMA_IS_GD2) {
return '<a href="transformation_wrapper.php'
. $options['wrapper_link']
. '" target="_blank"><img src="transformation_wrapper.php'
. '" rel="noopener noreferrer" target="_blank"><img src="transformation_wrapper.php'
. $options['wrapper_link'] . '&amp;resize=jpeg&amp;newWidth='
. (isset($options[0]) ? $options[0] : '100') . '&amp;newHeight='
. (isset($options[1]) ? $options[1] : 100)
. (isset($options[0]) ? intval($options[0]) : '100') . '&amp;newHeight='
. (isset($options[1]) ? intval($options[1]) : 100)
. '" alt="[' . htmlspecialchars($buffer) . ']" border="0" /></a>';
} else {
return '<img src="transformation_wrapper.php'

View File

@ -50,7 +50,7 @@ abstract class RegexValidationTransformationsPlugin extends IOTransformationsPlu
$this->success = false;
$this->error = sprintf(
__('Validation failed for the input string %s.'),
$buffer
htmlspecialchars($buffer)
);
}

View File

@ -49,13 +49,13 @@ abstract class TextImageLinkTransformationsPlugin extends TransformationsPlugin
$url = (isset($options[0]) ? $options[0] : '') . $buffer;
$parsed = parse_url($url);
/* Do not allow javascript links */
if (isset($parsed['scheme']) && $parsed['scheme'] == 'javascript') {
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https', 'ftp', 'mailto'))) {
return htmlspecialchars($url);
}
return '<a href="' . htmlspecialchars($url)
. '" target="_blank"><img src="' . htmlspecialchars($url)
. '" border="0" width="' . (isset($options[1]) ? $options[1] : 100)
. '" height="' . (isset($options[2]) ? $options[2] : 50) . '" />'
. '" rel="noopener noreferrer" target="_blank"><img src="' . htmlspecialchars($url)
. '" border="0" width="' . (isset($options[1]) ? intval($options[1]) : 100)
. '" height="' . (isset($options[2]) ? intval($options[2]) : 50) . '" />'
. htmlspecialchars($buffer) . '</a>';
}

View File

@ -49,14 +49,14 @@ abstract class TextLinkTransformationsPlugin extends TransformationsPlugin
$url = (isset($options[0]) ? $options[0] : '') . ((isset($options[2]) && $options[2]) ? '' : $buffer);
$parsed = parse_url($url);
/* Do not allow javascript links */
if (isset($parsed['scheme']) && $parsed['scheme'] == 'javascript') {
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https', 'ftp', 'mailto'))) {
return htmlspecialchars($url);
}
return '<a href="'
. htmlspecialchars($url)
. '" title="'
. htmlspecialchars(isset($options[1]) ? $options[1] : '')
. '" target="_new">'
. '" target="_blank" rel="noopener noreferrer">'
. htmlspecialchars(isset($options[1]) ? $options[1] : $buffer)
. '</a>';
}

View File

@ -261,7 +261,7 @@ function PMA_getTablePositions($pg)
1 AS `H`
FROM " . PMA\libraries\Util::backquote($cfgRelation['db'])
. "." . PMA\libraries\Util::backquote($cfgRelation['table_coords']) . "
WHERE pdf_page_number = " . $pg;
WHERE pdf_page_number = " . intval($pg);
$tab_pos = $GLOBALS['dbi']->fetchResult(
$query,
@ -290,7 +290,7 @@ function PMA_getPageName($pg)
$query = "SELECT `page_descr`"
. " FROM " . PMA\libraries\Util::backquote($cfgRelation['db'])
. "." . PMA\libraries\Util::backquote($cfgRelation['pdf_pages'])
. " WHERE " . PMA\libraries\Util::backquote('page_nr') . " = " . $pg;
. " WHERE " . PMA\libraries\Util::backquote('page_nr') . " = " . intval($pg);
$page_name = $GLOBALS['dbi']->fetchResult(
$query,
null,
@ -317,7 +317,7 @@ function PMA_deletePage($pg)
$query = "DELETE FROM " . PMA\libraries\Util::backquote($cfgRelation['db'])
. "." . PMA\libraries\Util::backquote($cfgRelation['table_coords'])
. " WHERE " . PMA\libraries\Util::backquote('pdf_page_number') . " = " . $pg;
. " WHERE " . PMA\libraries\Util::backquote('pdf_page_number') . " = " . intval($pg);
$success = PMA_queryAsControlUser(
$query, true, PMA\libraries\DatabaseInterface::QUERY_STORE
);
@ -325,7 +325,7 @@ function PMA_deletePage($pg)
if ($success) {
$query = "DELETE FROM " . PMA\libraries\Util::backquote($cfgRelation['db'])
. "." . PMA\libraries\Util::backquote($cfgRelation['pdf_pages'])
. " WHERE " . PMA\libraries\Util::backquote('page_nr') . " = " . $pg;
. " WHERE " . PMA\libraries\Util::backquote('page_nr') . " = " . intval($pg);
$success = PMA_queryAsControlUser(
$query, true, PMA\libraries\DatabaseInterface::QUERY_STORE
);
@ -364,7 +364,7 @@ function PMA_getDefaultPage($db)
);
if (count($default_page_no)) {
return $default_page_no[0];
return intval($default_page_no[0]);
}
return -1;
}
@ -406,7 +406,7 @@ function PMA_getLoadingPage($db)
$page_no = $min_page_no[0];
}
}
return $page_no;
return intval($page_no);
}
/**

View File

@ -1666,7 +1666,7 @@ function PMA_REL_renameTable($source_db, $target_db, $source_table, $target_tabl
* @param array $cfgRelation Relation configuration
* @param string $db database name
*
* @return string $pdf_page_number
* @return int $pdf_page_number
*/
function PMA_REL_createPage($newpage, $cfgRelation, $db)
{

View File

@ -295,7 +295,7 @@ function PMA_Replication_connectToMaster(
$server = array();
$server['user'] = $user;
$server['password'] = $password;
$server["host"] = $host;
$server["host"] = PMA_sanitizeMySQLHost($host);
$server["port"] = $port;
$server["socket"] = $socket;

View File

@ -549,7 +549,7 @@ function PMA_getHtmlForReplicationStatusTable($type, $hidden = false, $title = t
foreach (${"{$type}_variables"} as $variable) {
$html .= ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">';
$html .= ' <td class="name">';
$html .= $variable;
$html .= htmlspecialchars($variable);
$html .= ' </td>';
$html .= ' <td class="value">';
@ -572,13 +572,13 @@ function PMA_getHtmlForReplicationStatusTable($type, $hidden = false, $title = t
'Replicate_Do_Table', 'Replicate_Ignore_Table',
'Replicate_Wild_Do_Table', 'Replicate_Wild_Ignore_Table');
if (in_array($variable, $variables_wrap)) {
$html .= str_replace(
$html .= htmlspecialchars(str_replace(
',',
', ',
${"server_{$type}_replication"}[0][$variable]
);
));
} else {
$html .= ${"server_{$type}_replication"}[0][$variable];
$html .= htmlspecialchars(${"server_{$type}_replication"}[0][$variable]);
}
$html .= '</span>';
@ -807,7 +807,7 @@ function PMA_getHtmlForAddUserLoginForm($username_length)
. (empty($_REQUEST['username']) ? '' : ' value="'
. (isset($GLOBALS['new_username'])
? $GLOBALS['new_username']
: $_REQUEST['username']) . '"')
: htmlspecialchars($_REQUEST['username'])) . '"')
. ' />'
. '</div>';
@ -837,7 +837,7 @@ function PMA_getHtmlForTableInfoForm($hostname_length)
. '</span>'
. '<input type="text" name="hostname" id="pma_hostname" maxlength="'
. $hostname_length . '" value="'
. (isset($_REQUEST['hostname']) ? $_REQUEST['hostname'] : '')
. (isset($_REQUEST['hostname']) ? htmlspecialchars($_REQUEST['hostname']) : '')
. '" title="' . __('Host')
. '" />'
. PMA\libraries\Util::showHint(

View File

@ -2390,13 +2390,13 @@ function PMA_getHtmlTableBodyForSpecificDbRoutinePrivs($db, $odd_row, $index_che
. 'id="checkbox_sel_users_' . ($index_checkbox++) . '" '
. 'value="' . $value . '" /></td>';
$html_output .= '<td>' . $row['User']
$html_output .= '<td>' . htmlspecialchars($row['User'])
. '</td>'
. '<td>' . $row['Host']
. '<td>' . htmlspecialchars($row['Host'])
. '</td>'
. '<td>' . 'routine'
. '</td>'
. '<td>' . '<code>' . $row['Routine_name'] . '</code>'
. '<td>' . '<code>' . htmlspecialchars($row['Routine_name']) . '</code>'
. '</td>'
. '<td>' . 'Yes'
. '</td>';

View File

@ -285,7 +285,7 @@ function PMA_getHtmlForRenderVariables($ServerStatusData, $alerts, $strShowStatu
$retval .= '<span class="allfine">';
}
}
$retval .= $value;
$retval .= htmlspecialchars($value);
if (isset($alerts[$name])) {
$retval .= '</span>';
}

View File

@ -352,7 +352,7 @@ function PMA_editUserGroup($userGroup, $new = false)
}
$tabName = $tabGroupName . '_' . $tab;
$allowed = isset($_REQUEST[$tabName]) && $_REQUEST[$tabName] == 'Y';
$sql_query .= "('" . $userGroup . "', '" . $tabName . "', '"
$sql_query .= "('" . PMA_Util::sqlAddSlashes($userGroup) . "', '" . $tabName . "', '"
. ($allowed ? "Y" : "N") . "')";
$first = false;
}

View File

@ -75,7 +75,23 @@ function PMA_sessionFailed($errors)
{
$messages = array();
foreach ($errors as $error) {
$messages[] = $error->getMessage();
/*
* Remove path from open() in error message to avoid path disclossure
*
* This can happen with PHP 5 when nonexisting session ID is provided,
* since PHP 7, session existence is checked first.
*
* This error can also happen in case of session backed error (eg.
* read only filesystem) on any PHP version.
*
* The message string is currently hardcoded in PHP, so hopefully it
* will not change in future.
*/
$messages[] = preg_replace(
'/open(.*, O_RDWR)/',
'open(SESSION_FILE, O_RDWR)',
$error->getMessage()
);
}
/*

View File

@ -393,9 +393,7 @@ function PMA_getHtmlForTableVersionDetails(
function PMA_getTableLastVersionNumber($sql_result)
{
$maxversion = $GLOBALS['dbi']->fetchArray($sql_result);
$last_version = $maxversion['version'];
return $last_version;
return intval($maxversion['version']);
}
/**
@ -867,7 +865,10 @@ function PMA_getHtmlForSchemaSnapshot($url_query)
);
// Unserialize snapshot
$temp = unserialize($data['schema_snapshot']);
$temp = PMA_safeUnserialize($data['schema_snapshot']);
if ($temp === null) {
$temp = array('COLUMNS' => array(), 'INDEXES' => array());
}
$columns = $temp['COLUMNS'];
$indexes = $temp['INDEXES'];
$html .= PMA_getHtmlForColumns($columns);

View File

@ -143,19 +143,18 @@ function PMA_getNoOfFilesInZip($file)
/**
* Extracts a set of files from the given zip archive to a given destinations.
*
* @param string $zip_path path to the zip archive
* @param string $destination destination to extract files
* @param array $entries files in archive that should be extracted
* @param string $zip_path path to the zip archive
* @param string $entry file in the archive that should be extracted
*
* @return bool true on success, false otherwise
* @return string|bool data on sucess, false otherwise
*/
function PMA_zipExtract($zip_path, $destination, $entries)
function PMA_zipExtract($zip_path, $entry)
{
$zip = new ZipArchive;
if ($zip->open($zip_path) === true) {
$zip->extractTo($destination, $entries);
$result = $zip->getFromName($entry);
$zip->close();
return true;
return $result;
}
return false;
}

View File

@ -7,6 +7,8 @@
*/
use PMA\libraries\Linter;
$_GET['ajax_request'] = 'true';
/**
* Loading common files. Used to check for authorization, localization and to
* load the parsing library.

View File

@ -27,7 +27,7 @@ if (isset($_REQUEST['getColumns'])) {
exit;
}
if (isset($_REQUEST['splitColumn'])) {
$num_fields = $_REQUEST['numFields'];
$num_fields = min(4096, intval($_REQUEST['numFields']));
$html = PMA_getHtmlForCreateNewColumn($num_fields, $db, $table);
$html .= URL::getHiddenInputs($db, $table);
echo $html;

View File

@ -1,20 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* phpinfo() wrapper to allow displaying only when configured to do so.
*
* @package PhpMyAdmin
*/
/**
* Gets core libraries and defines some variables
*/
require_once 'libraries/common.inc.php';
PMA\libraries\Response::getInstance()->disable();
/**
* Displays PHP information
*/
if ($GLOBALS['cfg']['ShowPhpInfo']) {
phpinfo();
}

View File

@ -43,10 +43,13 @@ if (isset($_REQUEST['submit_num_fields'])) {
if (isset($_REQUEST['orig_field_where'])) {
$_REQUEST['field_where'] = $_REQUEST['orig_field_where'];
}
$num_fields = $_REQUEST['orig_num_fields'] + $_REQUEST['added_fields'];
$num_fields = min(
intval($_REQUEST['orig_num_fields']) + intval($_REQUEST['added_fields']),
4096
);
$regenerate = true;
} elseif (isset($_REQUEST['num_fields']) && intval($_REQUEST['num_fields']) > 0) {
$num_fields = (int) $_REQUEST['num_fields'];
$num_fields = min(4096, intval($_REQUEST['num_fields']));
} else {
$num_fields = 1;
}

View File

@ -21,6 +21,10 @@
? ' target="' . $url['target'] . '"'
: null;
?>
<?= !empty($url['target']) && $url['target'] == '_blank'
? ' rel="noopener noreferrer"'
: null;
?>
<?= !empty($url['id']) ? ' id="' . $url['id'] . '"' : null; ?>
<?= !empty($url['class'])
? ' class="' . $url['class'] . '"'

View File

@ -15,7 +15,7 @@
<input type="hidden" name="dbstats" value="1" />
<?php endif; ?>
<input type="text" name="new_db" value="<?= $GLOBALS['db_to_create']; ?>"
<input type="text" name="new_db" value="<?= htmlspecialchars($GLOBALS['db_to_create']); ?>"
maxlength="64" class="textfield" id="text_create_db" required
placeholder="<?= __('Database name'); ?>" />
<?= PMA\libraries\Charsets::getCollationDropdownBox('db_collation', null, null, true); ?>

View File

@ -10,8 +10,8 @@
<select name="visualizationSettings[labelColumn]" id="labelColumn" class="autosubmit">
<option value=""><?= __("-- None --"); ?></option>
<?php foreach ($labelCandidates as $value): ?>
<option value="<?= $value; ?>" <?= ($value == $visualizationSettings['labelColumn'] ? 'selected="selected"' : ''); ?>>
<?= $value; ?>
<option value="<?= htmlspecialchars($value); ?>" <?= ($value == $visualizationSettings['labelColumn'] ? 'selected="selected"' : ''); ?>>
<?= htmlspecialchars($value); ?>
</option>
<?php endforeach; ?>
</select>
@ -20,8 +20,8 @@
</label>
<select name="visualizationSettings[spatialColumn]" id="spatialColumn" class="autosubmit">
<?php foreach ($spatialCandidates as $value): ?>
<option value="<?= $value; ?>" <?= ($value == $visualizationSettings['spatialColumn'] ? 'selected="selected"' : ''); ?>>
<?= $value; ?>
<option value="<?= htmlspecialchars($value); ?>" <?= ($value == $visualizationSettings['spatialColumn'] ? 'selected="selected"' : ''); ?>>
<?= htmlspecialchars($value); ?>
</option>
<?php endforeach; ?>
</select>

View File

@ -16,7 +16,7 @@
</a>
</center>
<div id="querydata" style="display:none">
<?= json_encode($data); ?>
<?= htmlspecialchars(json_encode($data)); ?>
</div>
<div id="querychart"></div>
<button class="button-reset">

View File

@ -187,7 +187,7 @@ $rownum = 0; $odd_row = true; ?>
$tmp_partition_description = $firstPartition->getDescription();
$removeSQL = "ALTER TABLE " . Util::backquote($table) . " REMOVE PARTITIONING";
$removeUrl = 'sql.php' . $url_query . '&sql_query=' . urldecode($removeSQL);
$removeUrl = 'sql.php' . $url_query . '&sql_query=' . urlencode($removeSQL);
echo Template::get('table/structure/display_partitions')->render(
array(

View File

@ -1363,7 +1363,7 @@ class DisplayResultsTest extends PMATestCase
$meta,
$url_params,
null,
'<a href="1001" title="" target="_new">1001</a>'
'1001'
),
array(
false,
@ -1492,7 +1492,7 @@ class DisplayResultsTest extends PMATestCase
0,
'binary',
'<td class="left grid_edit transformed hex">'
. '<a href="1001" title="" target="_new">1001</a></td>'
. '1001</td>'
),
array(
'noblob',

View File

@ -252,7 +252,7 @@ class PbxtTest extends PMATestCase
. ' can be found on the %sPrimeBase XT Home Page%s.'
),
'<a href="' . PMA_linkURL('https://mariadb.com/kb/en/mariadb/about-pbxt/')
. '" target="_blank">',
. '" rel="noopener noreferrer" target="_blank">',
'</a>'
)
. '</p>' . "\n"

View File

@ -454,12 +454,12 @@ class AuthenticationCookieTest extends PMATestCase
$GLOBALS['cfg']['LoginCookieDeleteAll'] = true;
$GLOBALS['cfg']['Servers'] = array(1);
$_COOKIE['pmaPass-0'] = 'test';
$_COOKIE['pmaAuth-0'] = 'test';
$this->object->logOut();
$this->assertFalse(
isset($_COOKIE['pmaPass-0'])
isset($_COOKIE['pmaAuth-0'])
);
$attrInstance->setValue($restoreInstance);
}
@ -496,12 +496,12 @@ class AuthenticationCookieTest extends PMATestCase
$GLOBALS['cfg']['Servers'] = array(1);
$GLOBALS['server'] = 1;
$_COOKIE['pmaPass-1'] = 'test';
$_COOKIE['pmaAuth-1'] = 'test';
$this->object->logOut();
$this->assertFalse(
isset($_COOKIE['pmaPass-1'])
isset($_COOKIE['pmaAuth-1'])
);
$attrInstance->setValue($restoreInstance);
}
@ -541,7 +541,7 @@ class AuthenticationCookieTest extends PMATestCase
);
$this->assertFalse(
isset($_COOKIE['pmaPass-1'])
isset($_COOKIE['pmaAuth-1'])
);
}
@ -550,25 +550,19 @@ class AuthenticationCookieTest extends PMATestCase
*
* @return void
*/
public function testAuthCheckIV()
public function testAuthCheckInvalidCookie()
{
$GLOBALS['cfg']['AllowArbitraryServer'] = true;
$_REQUEST['pma_servername'] = 'testPMAServer';
$_REQUEST['pma_password'] = 'testPMAPSWD';
$_REQUEST['pma_username'] = '';
$GLOBALS['server'] = 1;
$_COOKIE['pmaServer-1'] = 'pmaServ1';
$_COOKIE['pmaUser-1'] = '';
$_COOKIE['pma_iv-1'] = base64_encode('testiv09testiv09');
$this->assertFalse(
$this->object->authCheck()
);
$this->assertEquals(
'pmaServ1',
$GLOBALS['pma_auth_server']
);
}
/**
@ -582,7 +576,7 @@ class AuthenticationCookieTest extends PMATestCase
$_COOKIE['pmaServer-1'] = 'pmaServ1';
$_COOKIE['pmaUser-1'] = 'pmaUser1';
$_COOKIE['pma_iv-1'] = base64_encode('testiv09testiv09');
$_COOKIE['pmaPass-1'] = '';
$_COOKIE['pmaAuth-1'] = '';
$GLOBALS['cfg']['blowfish_secret'] = 'secret';
$_SESSION['last_access_time'] = time() - 1000;
$GLOBALS['cfg']['LoginCookieValidity'] = 1440;
@ -642,7 +636,7 @@ class AuthenticationCookieTest extends PMATestCase
$_REQUEST['pma_username'] = '';
$_COOKIE['pmaServer-1'] = 'pmaServ1';
$_COOKIE['pmaUser-1'] = 'pmaUser1';
$_COOKIE['pmaPass-1'] = 'pmaPass1';
$_COOKIE['pmaAuth-1'] = 'pmaAuth1';
$_COOKIE['pma_iv-1'] = base64_encode('testiv09testiv09');
$GLOBALS['cfg']['blowfish_secret'] = 'secret';
$GLOBALS['cfg']['CaptchaLoginPrivateKey'] = '';
@ -658,7 +652,7 @@ class AuthenticationCookieTest extends PMATestCase
$this->object->expects($this->at(1))
->method('cookieDecrypt')
->will($this->returnValue(''));
->will($this->returnValue('{"password":""}'));
$this->assertTrue(
$this->object->authCheck()
@ -756,7 +750,7 @@ class AuthenticationCookieTest extends PMATestCase
);
$this->assertTrue(
isset($_COOKIE['pmaPass-1'])
isset($_COOKIE['pmaAuth-1'])
);
$arr['password'] = 'testPW';
@ -828,10 +822,6 @@ class AuthenticationCookieTest extends PMATestCase
$this->object->authSetUser();
$this->object->storeUserCredentials();
$this->assertTrue(
isset($_COOKIE['pmaServer-2'])
);
$attrInstance->setValue($restoreInstance);
}
@ -879,7 +869,7 @@ class AuthenticationCookieTest extends PMATestCase
->getMock();
$GLOBALS['server'] = 2;
$_COOKIE['pmaPass-2'] = 'pass';
$_COOKIE['pmaAuth-2'] = 'pass';
$GLOBALS['login_without_password_is_forbidden'] = '1';
@ -904,7 +894,7 @@ class AuthenticationCookieTest extends PMATestCase
->getMock();
$GLOBALS['server'] = 2;
$_COOKIE['pmaPass-2'] = 'pass';
$_COOKIE['pmaAuth-2'] = 'pass';
$GLOBALS['login_without_password_is_forbidden'] = '';
$GLOBALS['allowDeny_forbidden'] = '1';
@ -928,7 +918,7 @@ class AuthenticationCookieTest extends PMATestCase
->getMock();
$GLOBALS['server'] = 2;
$_COOKIE['pmaPass-2'] = 'pass';
$_COOKIE['pmaAuth-2'] = 'pass';
$GLOBALS['allowDeny_forbidden'] = '';
$GLOBALS['no_activity'] = '1';
@ -953,7 +943,7 @@ class AuthenticationCookieTest extends PMATestCase
->getMock();
$GLOBALS['server'] = 2;
$_COOKIE['pmaPass-2'] = 'pass';
$_COOKIE['pmaAuth-2'] = 'pass';
$dbi = $this->getMockBuilder('PMA\libraries\DatabaseInterface')
->disableOriginalConstructor()
@ -995,7 +985,7 @@ class AuthenticationCookieTest extends PMATestCase
$GLOBALS['dbi'] = $dbi;
$GLOBALS['server'] = 2;
$_COOKIE['pmaPass-2'] = 'pass';
$_COOKIE['pmaAuth-2'] = 'pass';
unset($GLOBALS['errno']);
@ -1034,7 +1024,7 @@ class AuthenticationCookieTest extends PMATestCase
);
$this->assertEquals(
256,
32,
strlen($result)
);
}
@ -1057,7 +1047,7 @@ class AuthenticationCookieTest extends PMATestCase
$result = $method->invoke($this->object, null);
$this->assertEquals(
md5('notEmpty'),
'notEmpty',
$result
);
}
@ -1072,7 +1062,7 @@ class AuthenticationCookieTest extends PMATestCase
$this->object->setIV('testiv09testiv09');
// works with the openssl extension active or inactive
$this->assertEquals(
'+coP/up/ZBTBwbiEpCUVXQ==',
'{"iv":"dGVzdGl2MDl0ZXN0aXYwOQ==","mac":"347aa45ae1ade00c980f31129ec2defef18b2bfd","payload":"YDEaxOfP9nD9q\/2pC6hjfQ=="}',
$this->object->cookieEncrypt('data123', 'sec321')
);
}
@ -1084,16 +1074,101 @@ class AuthenticationCookieTest extends PMATestCase
*/
public function testCookieDecrypt()
{
$this->object->setIV('testiv09testiv09');
// works with the openssl extension active or inactive
$this->assertEquals(
'data123',
$this->object->cookieDecrypt(
'+coP/up/ZBTBwbiEpCUVXQ==',
'{"iv":"dGVzdGl2MDl0ZXN0aXYwOQ==","mac":"347aa45ae1ade00c980f31129ec2defef18b2bfd","payload":"YDEaxOfP9nD9q\/2pC6hjfQ=="}',
'sec321'
)
);
}
/**
* Test for PMA\libraries\plugins\auth\AuthenticationConfig::cookieDecrypt
*
* @return void
*/
public function testCookieDecryptInvalid()
{
// works with the openssl extension active or inactive
$this->assertEquals(
false,
$this->object->cookieDecrypt(
'{"iv":0,"mac":0,"payload":0}',
'sec321'
)
);
}
/**
* Test for secret splitting using getAESSecret
*
* @return void
*
* @dataProvider secretsProvider
*/
public function testMACSecretSplit($secret, $mac, $aes)
{
$this->assertEquals(
$mac,
$this->object->getMACSecret($secret)
);
}
/**
* Test for secret splitting using getMACSecret and getAESSecret
*
* @return void
*
* @dataProvider secretsProvider
*/
public function testAESSecretSplit($secret, $mac, $aes)
{
$this->assertEquals(
$aes,
$this->object->getAESSecret($secret)
);
}
/**
* Data provider for secrets splitting.
*
* @return array
*/
public function secretsProvider()
{
return array(
// Optimal case
array(
'1234567890123456abcdefghijklmnop',
'1234567890123456',
'abcdefghijklmnop',
),
// Overlapping secret
array(
'12345678901234567',
'1234567890123456',
'2345678901234567',
),
// Short secret
array(
'1234567890123456',
'1234567890123451',
'2345678901234562',
),
// Really short secret
array(
'12',
'1111111111111111',
'2222222222222222',
),
// Too short secret
array(
'1',
'1111111111111111',
'1111111111111111',
),
);
}
}

View File

@ -162,7 +162,7 @@ class ExportPhparrayTest extends PMATestCase
*/
public function testExportDBHeader()
{
$GLOBALS['crlf'] = ' ';
$GLOBALS['crlf'] = "\n";
ob_start();
$this->assertTrue(
@ -171,7 +171,7 @@ class ExportPhparrayTest extends PMATestCase
$result = ob_get_clean();
$this->assertContains(
'// Database `db` ',
"/**\n * Database `db`\n */",
$result
);
}
@ -252,7 +252,7 @@ class ExportPhparrayTest extends PMATestCase
$result = ob_get_clean();
$this->assertEquals(
"\n" . '// `db`.`table`' . "\n" .
"\n" . '/* `db`.`table` */' . "\n" .
'$table = array(' . "\n" .
' array(\'c1\' => 1,\'\' => \'a\')' . "\n" .
');' . "\n",

View File

@ -528,6 +528,8 @@ class ExportXmlTest extends PMATestCase
public function testExportData()
{
$GLOBALS['xml_export_contents'] = true;
$GLOBALS['asfile'] = true;
$GLOBALS['output_charset_conversion'] = false;
$dbi = $this->getMockBuilder('PMA\libraries\DatabaseInterface')
->disableOriginalConstructor()
@ -586,33 +588,33 @@ class ExportXmlTest extends PMATestCase
$result = ob_get_clean();
$this->assertContains(
"&lt;!-- Table ta&lt;ble --&gt;",
"<!-- Table ta&lt;ble -->",
$result
);
$this->assertContains(
"&lt;table name=&quot;ta&amp;lt;ble&quot;&gt;",
"<table name=\"ta&lt;ble\">",
$result
);
$this->assertContains(
"&lt;column name=&quot;fName1&quot;&gt;NULL&lt;/column&gt;",
"<column name=\"fName1\">NULL</column>",
$result
);
$this->assertContains(
"&lt;column name=&quot;fNa&amp;quot;me2&quot;&gt;&amp;lt;a&amp;gt;" .
"&lt;/column&gt;",
"<column name=\"fNa&quot;me2\">&lt;a&gt;" .
"</column>",
$result
);
$this->assertContains(
"&lt;column name=&quot;fName3&quot;&gt;NULL&lt;/column&gt;",
"<column name=\"fName3\">NULL</column>",
$result
);
$this->assertContains(
"&lt;/table&gt;",
"</table>",
$result
);
}

View File

@ -778,8 +778,8 @@ class TransformationPluginsTest extends PMATestCase
array("./image/", "200", "wrapper_link"=>"PMA_wrapper_link")
),
'<a href="transformation_wrapper.phpPMA_wrapper_link" '
. 'target="_blank"><img src="transformation_wrapper.php'
. 'PMA_wrapper_link&amp;resize=jpeg&amp;newWidth=./image/&amp;'
. 'rel="noopener noreferrer" target="_blank"><img src="transformation_wrapper.php'
. 'PMA_wrapper_link&amp;resize=jpeg&amp;newWidth=0&amp;'
. 'newHeight=200" alt="[PMA_JPEG_Inline]" border="0" /></a>'
),
array(
@ -788,7 +788,7 @@ class TransformationPluginsTest extends PMATestCase
'PMA_IMAGE_LINK',
array("./image/", "200", "wrapper_link"=>"PMA_wrapper_link")
),
'<a class="disableAjax" target="_new"'
'<a class="disableAjax" target="_blank" rel="noopener noreferrer"'
. ' href="transformation_wrapper.phpPMA_wrapper_link"'
. ' alt="[PMA_IMAGE_LINK]">[BLOB]</a>'
),
@ -799,9 +799,9 @@ class TransformationPluginsTest extends PMATestCase
array("./image/", "200", "wrapper_link"=>"PMA_wrapper_link")
),
'<a href="transformation_wrapper.phpPMA_wrapper_link"'
. ' target="_blank"><img src="transformation_wrapper.php'
. ' rel="noopener noreferrer" target="_blank"><img src="transformation_wrapper.php'
. 'PMA_wrapper_link&amp;'
. 'resize=jpeg&amp;newWidth=./image/&amp;newHeight=200" '
. 'resize=jpeg&amp;newWidth=0&amp;newHeight=200" '
. 'alt="[PMA_PNG_Inline]" border="0" /></a>'
),
array(
@ -866,7 +866,25 @@ class TransformationPluginsTest extends PMATestCase
"<a ref='https://www.example.com/'>PMA_BUFFER</a>",
array("option1", "option2")
),
"<a ref='https://www.example.com/'>PMA_BUFFER</a>"
"<iframe srcdoc=\"<a ref='https://www.example.com/'>PMA_BUFFER</a>\" sandbox=\"\"></iframe>"
),
array(
new Text_Plain_Formatted(),
array(
"<a ref=\"https://www.example.com/\">PMA_BUFFER</a>",
array("option1", "option2")
),
"<iframe srcdoc=\"<a ref='https://www.example.com/'>PMA_BUFFER</a>\" sandbox=\"\"></iframe>"
),
array(
new Text_Plain_Imagelink(),
array(
'PMA_IMAGE',
array("http://image/", "200")
),
'<a href="http://image/PMA_IMAGE" rel="noopener noreferrer" target="_blank">'
. '<img src="http://image/PMA_IMAGE" border="0" width="200" '
. 'height="50" />PMA_IMAGE</a>'
),
array(
new Text_Plain_Imagelink(),
@ -874,9 +892,7 @@ class TransformationPluginsTest extends PMATestCase
'PMA_IMAGE',
array("./image/", "200")
),
'<a href="./image/PMA_IMAGE" target="_blank">'
. '<img src="./image/PMA_IMAGE" border="0" width="200" '
. 'height="50" />PMA_IMAGE</a>'
'./image/PMA_IMAGE'
),
array(
new Text_Plain_Sql(),
@ -894,8 +910,32 @@ class TransformationPluginsTest extends PMATestCase
'PMA_TXT_LINK',
array("./php/", "text_name")
),
'<a href="./php/PMA_TXT_LINK"'
. ' title="text_name" target="_new">text_name</a>'
'./php/PMA_TXT_LINK'
),
array(
new Text_Plain_Link(),
array(
'PMA_TXT_LINK',
array(),
),
'PMA_TXT_LINK'
),
array(
new Text_Plain_Link(),
array(
'https://example.com/PMA_TXT_LINK',
array(),
),
'<a href="https://example.com/PMA_TXT_LINK" title=""'
. ' target="_blank" rel="noopener noreferrer">https://example.com/PMA_TXT_LINK</a>'
),
array(
new Text_Plain_Link(),
array(
'PMA_TXT_LINK',
array("./php/", "text_name")
),
'./php/PMA_TXT_LINK'
),
array(
new Text_Plain_Longtoipv4(),

View File

@ -44,39 +44,64 @@ class PMA_Ip_Allow_Deny_Test extends PHPUnit_Framework_TestCase
$GLOBALS['cfg']['Server']['AllowDeny']['rules'][] = "deny % 255.255.0.0/8";
$GLOBALS['cfg']['Server']['AllowDeny']['rules'][]
= "deny % from 255.255.0.0/8";
include_once 'libraries/ip_allow_deny.lib.php';
}
/**
* Test for PMA_getIp
*
* @return void
*
* @dataProvider proxyIPs
*/
public function testGetIp()
public function testGetIp($remote, $header, $expected, $proxyip = null)
{
//$_SERVER['REMOTE_ADDR'] is empty
unset($_SERVER['REMOTE_ADDR']);
unset($_SERVER['TEST_FORWARDED_HEADER']);
$GLOBALS['cfg']['TrustedProxies'] = array();
if (!is_null($remote)) {
$_SERVER['REMOTE_ADDR'] = $remote;
}
if (!is_null($header)) {
if (is_null($proxyip)) {
$proxyip = $remote;
}
$GLOBALS['cfg']['TrustedProxies'][$proxyip] = 'TEST_FORWARDED_HEADER';
$_SERVER['TEST_FORWARDED_HEADER'] = $header;
}
$this->assertEquals(
false,
$expected,
PMA_getIp()
);
$_SERVER['REMOTE_ADDR'] = "101.0.0.25";
$this->assertEquals(
"101.0.0.25",
PMA_getIp()
);
unset($_SERVER['REMOTE_ADDR']);
unset($_SERVER['TEST_FORWARDED_HEADER']);
$GLOBALS['cfg']['TrustedProxies'] = array();
}
//proxy
$var_name = "direct_ip";
$direct_ip = $_SERVER['REMOTE_ADDR'];
$GLOBALS['cfg']['TrustedProxies'][$direct_ip] = $var_name;
$_SERVER[$var_name] = "192.168.0.1";
$this->assertEquals(
"192.168.0.1",
PMA_getIp()
/**
* Data provider for PMA_getIp tests
*
* @return array
*/
public function proxyIPs()
{
return array(
// Nothing set
array(null, null, false),
// Remote IP set
array('101.0.0.25', null, '101.0.0.25'),
// Proxy
array('101.0.0.25', '192.168.10.10', '192.168.10.10'),
// Several proxies
array('101.0.0.25', '192.168.10.1, 192.168.100.100', '192.168.10.1'),
// Invalid proxy
array('101.0.0.25', 'invalid', false),
// Direct IP with proxy enabled
array('101.0.0.25', '192.168.10.10', '101.0.0.25', '10.10.10.10'),
);
unset($_SERVER[$var_name]);
unset($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
}
/**

View File

@ -118,10 +118,16 @@ class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
public function testZipExtract()
{
$this->assertEquals(
false,
PMA_zipExtract(
'./test/test_data/test.zip', './test/test_data/', 'wrongName'
),
true
'./test/test_data/test.zip', 'wrongName'
)
);
$this->assertEquals(
"TEST FILE\n",
PMA_zipExtract(
'./test/test_data/test.zip', 'test.file'
)
);
}

View File

@ -0,0 +1,53 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Test for PMA_isAllowedDomain
*
* @package PhpMyAdmin-test
*/
/*
* Include to test.
*/
require_once 'libraries/core.lib.php';
class PMA_isAllowedDomain_test extends PHPUnit_Framework_TestCase
{
/**
* Test for unserializing
*
* @param string $url URL to test
* @param mixed $expected Expected result
*
* @return void
*
* @dataProvider provideURLs
*/
function testIsAllowedDomain($url, $expected)
{
$_SERVER['SERVER_NAME'] = 'server.local';
$this->assertEquals(
$expected,
PMA_isAllowedDomain($url)
);
}
/**
* Test data provider
*
* @return array
*/
function provideURLs()
{
return array(
array('https://www.phpmyadmin.net/', true),
array('http://duckduckgo.com\\@github.com', false),
array('https://github.com/', true),
array('https://server.local/', true),
array('./relative/', false),
);
}
}

View File

@ -0,0 +1,55 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Test for PMA_safeUnserialize
*
* @package PhpMyAdmin-test
*/
/*
* Include to test.
*/
require_once 'libraries/core.lib.php';
class PMA_safeUnserialize_test extends PHPUnit_Framework_TestCase
{
/**
* Test for unserializing
*
* @param string $data Serialized data
* @param mixed $expected Expected result
*
* @return void
*
* @dataProvider provideMySQLHosts
*/
function testSanitizeMySQLHost($data, $expected)
{
$this->assertEquals(
$expected,
PMA_safeUnserialize($data)
);
}
/**
* Test data provider
*
* @return array
*/
function provideMySQLHosts()
{
return array(
array('s:6:"foobar";', 'foobar'),
array('foobar', null),
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(serialize(array(1, 2, 3)), array(1, 2, 3)),
array(serialize('string""'), 'string""'),
array(serialize(array('foo' => 'bar')), array('foo' => 'bar')),
array(serialize(array('1', new stdClass(), '2')), null),
);
}
}

View File

@ -0,0 +1,48 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Test for PMA_sanitizeMySQLHost
*
* @package PhpMyAdmin-test
*/
/*
* Include to test.
*/
require_once 'libraries/core.lib.php';
class PMA_sanitizeMySQLHost_test extends PHPUnit_Framework_TestCase
{
/**
* Test for MySQL host sanitizing
*
* @param string $host Test host name
* @param string $expected Expected result
*
* @return void
*
* @dataProvider provideMySQLHosts
*/
function testSanitizeMySQLHost($host, $expected)
{
$this->assertEquals(
$expected,
PMA_sanitizeMySQLHost($host)
);
}
/**
* Test data provider
*
* @return array
*/
function provideMySQLHosts()
{
return array(
array('p:foo.bar', 'foo.bar'),
array('bar.baz', 'bar.baz'),
array('P:example.com', 'example.com'),
);
}
}

View File

@ -23,7 +23,7 @@ $hash = '#pma_' . preg_replace('/([0-9]*)\.([0-9]*)\..*/', '\1_\2', PMA_VERSI
$url = PMA_linkURL('https://www.phpmyadmin.net/themes/') . $hash;
$output = '<h1>phpMyAdmin - ' . __('Theme') . '</h1>';
$output .= '<p>';
$output .= '<a href="' . $url . '" class="_blank">';
$output .= '<a href="' . $url . '" rel="noopener noreferrer" class="_blank">';
$output .= __('Get more themes!');
$output .= '</a>';
$output .= '</p>';

View File

@ -34,9 +34,20 @@ $request_params = array(
'transform_key',
'where_clause'
);
$size_params = array(
'newHeight',
'newWidth',
);
foreach ($request_params as $one_request_param) {
if (isset($_REQUEST[$one_request_param])) {
$GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
if (in_array($one_request_param, $size_params)) {
$GLOBALS[$one_request_param] = intval($_REQUEST[$one_request_param]);
if ($GLOBALS[$one_request_param] > 2000) {
$GLOBALS[$one_request_param] = 2000;
}
} else {
$GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
}
}
}
@ -91,7 +102,7 @@ $response->getHeader()->sendHttpHeaders();
if (isset($ct) && ! empty($ct)) {
$mime_type = $ct;
} else {
$mime_type = (isset($mime_map[$transform_key]['mimetype'])
$mime_type = (!empty($mime_map[$transform_key]['mimetype'])
? str_replace('_', '/', $mime_map[$transform_key]['mimetype'])
: $default_ct)
. (isset($mime_options['charset']) ? $mime_options['charset'] : '');
@ -100,7 +111,11 @@ if (isset($ct) && ! empty($ct)) {
PMA_downloadHeader($cn, $mime_type);
if (! isset($_REQUEST['resize'])) {
echo $row[$transform_key];
if (stripos($mime_type, 'html') === false) {
echo $row[$transform_key];
} else {
echo htmlspecialchars($row[$transform_key]);
}
} else {
// if image_*__inline.inc.php finds that we can resize,
// it sets the resize parameter to jpeg or png

View File

@ -13,6 +13,11 @@ use PMA\libraries\Sanitize;
define('PMA_MINIMUM_COMMON', true);
require_once './libraries/common.inc.php';
// Only output the http headers
$response = PMA\libraries\Response::getInstance();
$response->getHeader()->sendHttpHeaders();
$response->disable();
if (! PMA_isValid($_REQUEST['url'])
|| ! preg_match('/^https:\/\/[^\n\r]*$/', $_REQUEST['url'])
|| ! PMA_isAllowedDomain($_REQUEST['url'])

View File

@ -121,6 +121,9 @@ function PMA_setChangePasswordMsg()
__('The passwords aren\'t the same!')
);
$error = true;
} elseif (strlen($_REQUEST['pma_pw']) > 256) {
$message = PMA_Message::error(__('Password is too long!'));
$error = true;
}
}
return array('error' => $error, 'msg' => $message);

View File

@ -9,9 +9,12 @@
// Sets up the session
use PMA\libraries\VersionInformation;
define('PMA_MINIMUM_COMMON', true);
$_GET['ajax_request'] = 'true';
require_once 'libraries/common.inc.php';
require_once 'libraries/VersionInformation.php';
// Disabling standard response.
PMA\libraries\Response::getInstance()->disable();
// Always send the correct headers
PMA_headerJSON();