VYPR
Medium severity5.3NVD Advisory· Published Jul 3, 2016· Updated May 6, 2026

CVE-2016-5730

CVE-2016-5730

Description

phpMyAdmin 4.0.x before 4.0.10.16, 4.4.x before 4.4.15.7, and 4.6.x before 4.6.3 allows remote attackers to obtain sensitive information via vectors involving (1) an array value to FormDisplay.php, (2) incorrect data to validate.php, (3) unexpected data to Validator.php, (4) a missing config directory during setup, or (5) an incorrect OpenID identifier data type, which reveals the full path in an error message.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

phpMyAdmin versions prior to 4.6.3, 4.4.15.7, and 4.0.10.16 disclose the full server path via error messages due to improper handling of crafted input in multiple components.

Vulnerability

Multiple full path disclosure vulnerabilities exist in phpMyAdmin 4.0.x before 4.0.10.16, 4.4.x before 4.4.15.7, and 4.6.x before 4.6.3 [1][4]. The issue arises when the application encounters specially crafted requests affecting components such as FormDisplay.php, validate.php, Validator.php, or when a missing config directory during setup or incorrect OpenID identifier data type is provided. In these cases, phpMyAdmin displays a PHP error message that reveals the full filesystem path of the installation directory [4]. The vulnerabilities are triggered by passing an array value to FormDisplay.php, providing incorrect data to validate.php, unexpected data to Validator.php, a missing config directory during setup, or an incorrect OpenID identifier data type [1].

Exploitation

An attacker can exploit these vulnerabilities from a remote network position without requiring authentication [4]. The attacker crafts specific HTTP requests to the vulnerable phpMyAdmin endpoints. For example, sending an array value to FormDisplay.php or providing incorrect data to validate.php causes the application to generate a PHP error that includes the full installation path in the error message. The setup script (in /setup/) and example OpenID authentication script are also noted as attack vectors [4]. The exact steps vary by vector, but all involve sending malformed or unexpected input to trigger the error output.

Impact

Successful exploitation allows an attacker to obtain the full server-side filesystem path where phpMyAdmin is installed. This information disclosure can aid further attacks, such as path traversal or targeted exploitation of other vulnerabilities. The impact is limited to information disclosure and does not directly lead to code execution or privilege escalation [4]. The severity is considered non-critical by the vendor [4].

Mitigation

The vulnerabilities are fixed in phpMyAdmin versions 4.0.10.16, 4.4.15.7, and 4.6.3 [1][4]. Users should upgrade to these versions or later. As a mitigation factor, administrators can remove the setup script and examples subdirectories (./setup/ and ./examples/) to prevent exploitation via those paths [4]. The vendor has also provided specific patches for each branch as listed in the advisory [4].

AI Insight generated on May 23, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
phpmyadmin/phpmyadminPackagist
>= 4.0, < 4.0.10.164.0.10.16
phpmyadmin/phpmyadminPackagist
>= 4.4, < 4.4.15.74.4.15.7
phpmyadmin/phpmyadminPackagist
>= 4.6, < 4.6.34.6.3

Affected products

65
  • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.0:*:*:*:*:*:*:*+ 59 more
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.0:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.10:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.11:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.12:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.13:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.14:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.15:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.2:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.3:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.4:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.5:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.6:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.7:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.8:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.10.9:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.2:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.3:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.4:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.4.2:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.5:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.6:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.7:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.8:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.0.9:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.0:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.10:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.11:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.12:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.13:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.13.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.14.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.15:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.15.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.15.2:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.15.3:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.15.4:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.15.5:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.15.6:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.2:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.3:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.4:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.5:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.6:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.7:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.8:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.4.9:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.6.0:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.6.0:alpha1:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.6.0:rc1:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.6.0:rc2:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:phpmyadmin:phpmyadmin:4.6.2:*:*:*:*:*:*:*
    • (no CPE)range: <4.0.10.16 || >=4.4.0 <4.4.15.7 || >=4.6.0 <4.6.3
  • cpe:2.3:o:opensuse:leap:42.1:*:*:*:*:*:*:*
  • OpenSUSE/openSUSE2 versions
    cpe:2.3:o:opensuse:opensuse:13.1:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:o:opensuse:opensuse:13.1:*:*:*:*:*:*:*
    • cpe:2.3:o:opensuse:opensuse:13.2:*:*:*:*:*:*:*
  • ghsa-coords2 versions
    >= 4.0, < 4.0.10.16+ 1 more
    • (no CPE)range: >= 4.0, < 4.0.10.16
    • (no CPE)range: < 4.6.5.2-1.1

Patches

5
27664605b945

Improve error handling in OpenID example

https://github.com/phpmyadmin/phpmyadminMichal ČihařJun 17, 2016via ghsa
1 file changed · +3 3
  • examples/openid.php+3 3 modified
    @@ -98,9 +98,9 @@ function Show_page($contents)
     }
     
     /* Grab identifier */
    -if (isset($_POST['identifier'])) {
    +if (isset($_POST['identifier']) && is_string($_POST['identifier'])) {
         $identifier = $_POST['identifier'];
    -} else if (isset($_SESSION['identifier'])) {
    +} else if (isset($_SESSION['identifier']) && is_string($_SESSION['identifier'])) {
         $identifier = $_SESSION['identifier'];
     } else {
         $identifier = null;
    @@ -109,7 +109,7 @@ function Show_page($contents)
     /* Create OpenID object */
     try {
         $o = new OpenID_RelyingParty($returnTo, $realm, $identifier);
    -} catch (OpenID_Exception $e) {
    +} catch (Exception $e) {
         $contents = "<div class='relyingparty_results'>\n";
         $contents .= "<pre>" . $e->getMessage() . "</pre>\n";
         $contents .= "</div class='relyingparty_results'>";
    
331c560fbfa0

Improve error handling in setup in case config dir is not present

https://github.com/phpmyadmin/phpmyadminMichal ČihařJun 17, 2016via ghsa
2 files changed · +42 5
  • setup/config.php+28 5 modified
    @@ -15,6 +15,24 @@
     
     require './libraries/config/setup.forms.php';
     
    +/**
    + * Loads configuration file path
    + *
    + * Do this in a function to avoid messing up with global $cfg
    + *
    + * @param string $config_file_path
    + *
    + * @return array
    + */
    +function loadConfig($config_file_path)
    +{
    +    $cfg = array();
    +    if (file_exists($config_file_path)) {
    +        include $config_file_path;
    +    }
    +    return $cfg;
    +}
    +
     $form_display = new FormDisplay($GLOBALS['ConfigFile']);
     $form_display->registerForm('_config.php', $forms['_config.php']);
     $form_display->save('_config.php');
    @@ -44,20 +62,25 @@
         //
         // Save generated config file on the server
         //
    -    file_put_contents(
    +    $result = @file_put_contents(
             $config_file_path,
             ConfigGenerator::getConfigFile($GLOBALS['ConfigFile'])
         );
    +    if ($result === false) {
    +        $state = 'config_not_saved';
    +    } else {
    +        $state = 'config_saved';
    +    }
         header('HTTP/1.1 303 See Other');
    -    header('Location: index.php' . PMA_URL_getCommon() . '&action_done=config_saved');
    +    header('Location: index.php' . PMA_URL_getCommon() . '&action_done=' . $state);
         exit;
     } elseif (PMA_ifSetOr($_POST['submit_load'], '')) {
         //
         // Load config file from the server
         //
    -    $cfg = array();
    -    include $config_file_path;
    -    $GLOBALS['ConfigFile']->setConfigData($cfg);
    +    $GLOBALS['ConfigFile']->setConfigData(
    +        loadConfig($config_file_path)
    +    );
         header('HTTP/1.1 303 See Other');
         header('Location: index.php' . PMA_URL_getCommon());
         exit;
    
  • setup/frames/index.inc.php+14 0 modified
    @@ -126,6 +126,20 @@
             )
         );
         break;
    +case 'config_not_saved':
    +    /* Use uniqid to display this message every time configuration is saved */
    +    PMA_messagesSet(
    +        'notice', uniqid('config_not_saved'), __('Configuration not saved!'),
    +        PMA_sanitize(
    +            __(
    +                'Please create web server writable folder [em]config[/em] in '
    +                . 'phpMyAdmin top level directory as described in '
    +                . '[doc@setup_script]documentation[/doc]. Otherwise you will be '
    +                . 'only able to download or display it.'
    +            )
    +        )
    +    );
    +    break;
     default:
         break;
     }
    
cd229d718e8c

Validate input of validator

https://github.com/phpmyadmin/phpmyadminMichal ČihařJun 17, 2016via ghsa
1 file changed · +38 23
  • libraries/config/Validator.php+38 23 modified
    @@ -8,6 +8,7 @@
     namespace PMA\libraries\config;
     
     use PMA\libraries\DatabaseInterface;
    +use PMA\libraries\Util;
     
     /**
      * Validation class for various validation functions
    @@ -280,6 +281,11 @@ public static function validateServer($path, $values)
                 'Servers/1/SignonURL' => ''
             );
             $error = false;
    +        if (empty($values['Servers/1/auth_type'])) {
    +            $values['Servers/1/auth_type'] = '';
    +            $result['Servers/1/auth_type'] = __('Invalid authentication type!');
    +            $error = true;
    +        }
             if ($values['Servers/1/auth_type'] == 'config'
                 && empty($values['Servers/1/user'])
             ) {
    @@ -308,14 +314,14 @@ public static function validateServer($path, $values)
             }
     
             if (! $error && $values['Servers/1/auth_type'] == 'config') {
    -            $password = $values['Servers/1/nopassword'] ? null
    -                : $values['Servers/1/password'];
    +            $password = !empty($values['Servers/1/nopassword']) && $values['Servers/1/nopassword'] ? null
    +                : (empty($values['Servers/1/password']) ? '' : $values['Servers/1/password']);
                 $test = static::testDBConnection(
    -                $values['Servers/1/connect_type'],
    -                $values['Servers/1/host'],
    -                $values['Servers/1/port'],
    -                $values['Servers/1/socket'],
    -                $values['Servers/1/user'],
    +                empty($values['Servers/1/connect_type']) ? '' : $values['Servers/1/connect_type'],
    +                empty($values['Servers/1/host']) ? '' : $values['Servers/1/host'],
    +                empty($values['Servers/1/port']) ? '' : $values['Servers/1/port'],
    +                empty($values['Servers/1/socket']) ? '' : $values['Servers/1/socket'],
    +                empty($values['Servers/1/user']) ? '' : $values['Servers/1/user'],
                     $password,
                     'Server'
                 );
    @@ -345,19 +351,19 @@ public static function validatePMAStorage($path, $values)
             );
             $error = false;
     
    -        if ($values['Servers/1/pmadb'] == '') {
    +        if (empty($values['Servers/1/pmadb'])) {
                 return $result;
             }
     
             $result = array();
    -        if ($values['Servers/1/controluser'] == '') {
    +        if (empty($values['Servers/1/controluser'])) {
                 $result['Servers/1/controluser'] = __(
                     'Empty phpMyAdmin control user while using phpMyAdmin configuration '
                     . 'storage!'
                 );
                 $error = true;
             }
    -        if ($values['Servers/1/controlpass'] == '') {
    +        if (empty($values['Servers/1/controlpass'])) {
                 $result['Servers/1/controlpass'] = __(
                     'Empty phpMyAdmin control user password while using phpMyAdmin '
                     . 'configuration storage!'
    @@ -366,10 +372,13 @@ public static function validatePMAStorage($path, $values)
             }
             if (! $error) {
                 $test = static::testDBConnection(
    -                $values['Servers/1/connect_type'],
    -                $values['Servers/1/host'], $values['Servers/1/port'],
    -                $values['Servers/1/socket'], $values['Servers/1/controluser'],
    -                $values['Servers/1/controlpass'], 'Server_pmadb'
    +                empty($values['Servers/1/connect_type']) ? '' : $values['Servers/1/connect_type'],
    +                empty($values['Servers/1/host']) ? '' : $values['Servers/1/host'],
    +                empty($values['Servers/1/port']) ? '' : $values['Servers/1/port'],
    +                empty($values['Servers/1/socket']) ? '' : $values['Servers/1/socket'],
    +                empty($values['Servers/1/controluser']) ? '' : $values['Servers/1/controluser'],
    +                empty($values['Servers/1/controlpass']) ? '' : $values['Servers/1/controlpass'],
    +                'Server_pmadb'
                 );
                 if ($test !== true) {
                     $result = array_merge($result, $test);
    @@ -391,7 +400,7 @@ public static function validateRegex($path, $values)
         {
             $result = array($path => '');
     
    -        if ($values[$path] == '') {
    +        if (empty($values[$path])) {
                 return $result;
             }
     
    @@ -400,7 +409,7 @@ public static function validateRegex($path, $values)
             $matches = array();
             // in libraries/ListDatabase.php _checkHideDatabase(),
             // a '/' is used as the delimiter for hide_db
    -        preg_match('/' . $values[$path] . '/', '', $matches);
    +        preg_match('/' . Util::requestString($values[$path]) . '/', '', $matches);
     
             static::testPHPErrorMsg(false);
     
    @@ -428,10 +437,11 @@ public static function validateTrustedProxies($path, $values)
                 return $result;
             }
     
    -        if (is_array($values[$path])) {
    +        if (is_array($values[$path]) || is_object($values[$path])) {
                 // value already processed by FormDisplay::save
                 $lines = array();
                 foreach ($values[$path] as $ip => $v) {
    +                $v = Util::requestString($v);
                     $lines[] = preg_match('/^-\d+$/', $ip)
                         ? $v
                         : $ip . ': ' . $v;
    @@ -483,14 +493,16 @@ public static function validateNumber(
             $max_value,
             $error_string
         ) {
    -        if ($values[$path] === '') {
    +        if (empty($values[$path])) {
                 return '';
             }
     
    -        if (intval($values[$path]) != $values[$path]
    -            || (! $allow_neg && $values[$path] < 0)
    -            || (! $allow_zero && $values[$path] == 0)
    -            || $values[$path] > $max_value
    +        $value = Util::requestString($values[$path]);
    +
    +        if (intval($value) != $value
    +            || (! $allow_neg && $value < 0)
    +            || (! $allow_zero && $value == 0)
    +            || $value > $max_value
             ) {
                 return $error_string;
             }
    @@ -576,7 +588,10 @@ public static function validateNonNegativeNumber($path, $values)
          */
         public static function validateByRegex($path, $values, $regex)
         {
    -        $result = preg_match($regex, $values[$path]);
    +        if (!isset($values[$path])) {
    +            return '';
    +        }
    +        $result = preg_match($regex, Util::requestString($values[$path]));
             return array($path => ($result ? '' : __('Incorrect value!')));
         }
     
    
96e0aa35653e

Fix error reporting on invalid request data

https://github.com/phpmyadmin/phpmyadminMichal ČihařJun 17, 2016via ghsa
1 file changed · +4 1
  • setup/validate.php+4 1 modified
    @@ -26,6 +26,9 @@
     $values = (array)$values;
     $result = PMA\libraries\config\Validator::validate($GLOBALS['ConfigFile'], $vids, $values, true);
     if ($result === false) {
    -    $result = 'Wrong data or no validation for ' . $vids;
    +    $result = sprintf(
    +        __('Wrong data or no validation for %s'),
    +        implode(',', $vids)
    +    );
     }
     echo $result !== true ? json_encode($result) : '';
    
b0180f18c828

Properly convert POST parameters

https://github.com/phpmyadmin/phpmyadminMichal ČihařJun 17, 2016via ghsa
1 file changed · +19 4
  • libraries/config/FormDisplay.php+19 4 modified
    @@ -639,12 +639,12 @@ public function save($forms, $allow_partial_save = true)
                     // cast variables to correct type
                     switch ($type) {
                     case 'double':
    -                    settype($_POST[$key], 'float');
    +                    settype($this->_trimString($_POST[$key]), 'float');
                         break;
                     case 'boolean':
                     case 'integer':
                         if ($_POST[$key] !== '') {
    -                        settype($_POST[$key], $type);
    +                        settype($this->_trimString($_POST[$key]), $type);
                         }
                         break;
                     case 'select':
    @@ -660,7 +660,7 @@ public function save($forms, $allow_partial_save = true)
                         break;
                     case 'string':
                     case 'short_string':
    -                    $_POST[$key] = trim($_POST[$key]);
    +                    $_POST[$key] = $this->_trimString($_POST[$key]);
                         break;
                     case 'array':
                         // eliminate empty values and ensure we have an array
    @@ -876,10 +876,25 @@ private function _setComments($system_path, array &$opts)
         private function _fillPostArrayParameters($post_values, $key)
         {
             foreach ($post_values as $v) {
    -            $v = trim($v);
    +            $v = $this->_trimString($v);
                 if ($v !== '') {
                     $_POST[$key][] = $v;
                 }
             }
         }
    +
    +    /*
    +     * Converts given (request) paramter to string
    +     *
    +     * @param mixed $value Value to convert
    +     *
    +     * @return string
    +     */
    +    private function _trimString($value)
    +    {
    +        while (is_array($value)) {
    +            $value = reset($value);
    +        }
    +        return trim((string)$value);
    +    }
     }
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

13

News mentions

0

No linked articles in our index yet.