Security can be examined at the following various levels:
Suppose an unauthorized person is trying to use our copy of phpMyAdmin. If we use the simple config
authentication type, anyone knowing the URL of our phpMyAdmin will have the same effective rights to our data as we do. In this case, we should use the directory protection mechanism offered by our web server (for example, .htaccess
, a file name with a leading dot) to add a level of protection. More details are available at http://en.wikipedia.org/wiki/Basic_access_authentication.
If we decide on using http
or cookie
authentication types, our data would be safe enough. However, we should take normal precautions with our password (including its periodic change).
The directory where phpMyAdmin is installed contains sensitive data. Not only the configuration file but also all scripts stored there must be protected from alteration. We should ensure that apart from us, only the web server effective user has read access to the files contained in this directory, and that only we can write to them.
phpMyAdmin's scripts never have to modify anything inside this directory, except when we use the Save export file to server feature (explained in Chapter 6).
Another recommendation is to rename the default phpMyAdmin
directory to something less obvious; this discourages probing of our server. This is called security by obscurity and can be very effective—but avoid choosing other obvious names such as admin
.
Another possible attack is from other developers having an account on the same web server as we do. In this kind of attack, someone can try to open our config.inc.php
file. As this file is readable by the web server, someone could try to include our file from their PHP scripts. This is why it is recommended to use PHP's open_basedir
feature, possibly applying it to all directories from which such attacks could originate. More details can be found at http://php.net/manual/en/ini.core.php#ini.open-basedir.
phpMyAdmin uses the PHP's custom error-handler mechanism. One of the benefits of this error handler is to avoid path disclosure, which is considered a security weakness. The default settings related to this are:
$cfg['Error_Handler'] = array(); $cfg['Error_Handler']['display'] = false;
You should let the default value for display be false
, unless you are developing a new phpMyAdmin feature and want to see all PHP errors and warnings.
An additional level of protection can be implemented, this time verifying the Internet Protocol (IP) address of the machine from which the request is received. To achieve this level of protection, we construct rules allowing or denying access, and specify the order in which these rules will be applied.
<'allow' | 'deny'> <username> [from] <source>
The from
keyword being optional; here are some examples:
Rule |
Description |
---|---|
|
User |
|
User |
|
User |
|
|
Usually we will have several rules. Let us say we wish to have the following two rules:
allow Marc from 45.34.23.12 allow Melanie from all
We have to put them in config.inc.php
(in the related server-specific section) as follows:
$cfg['Servers'][$i]['AllowDeny']['rules'] = array('allow Marc from 45.34.23.12', 'allow Melanie from all'),
When defining a single rule or multiple rules, a PHP array is used. We must follow its syntax, enclosing each complete rule within single quotes and separating each rule from the next with a comma. Thus, if we have only one rule, we must still use an array to specify it. The next parameter explains the order in which rules are interpreted.
By default, this parameter is empty:
$cfg['Servers'][$i]['AllowDeny']['order'] = '';
This means that no IP-based verification is made.
Suppose we want to allow access by default, denying access only to some username/IP pairs, we should use:
$cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';
In this case, all deny
rules will be applied first, followed by allow
rules. If a case is not mentioned in the rules, access is granted. Being more restrictive, we would want to deny by default. We can use:
$cfg['Servers'][$i]['AllowDeny']['order'] = 'allow,deny';
This time, all allow
rules are applied first, followed by deny
rules. If a case is not mentioned in the rules, access is denied. The third (and most restrictive) way of specifying rules order is:
$cfg['Servers'][$i]['AllowDeny']['order'] = 'explicit';
Now, deny
rules are applied before allow
rules. A username/IP address pair must be listed in the allow
rules and must not be listed in the deny
rules, for access to be granted.
As the root
user is present in almost all MySQL installations, it's often the target of attacks. A parameter permits us to easily block all phpMyAdmin logins of the MySQL's root
account, using the following:
$cfg['Servers'][$i]['AllowRoot'] = FALSE;
Some system administrators prefer to disable the root
account at the MySQL server level, creating another less obvious account possessing the same privileges. This has the advantage of blocking root
access from all sources, not just from phpMyAdmin.
HTTP is not inherently immune to network sniffing (grabbing sensitive data off the wire). So, if we want to protect not only our username and password but all the data that travels between our web server and browser, then we have to use HTTPS.
To do so, assuming that our web server supports HTTPS, we just have to start phpMyAdmin by putting https
instead of http
in the URL as follows:
https://www.mydomain.com/phpMyAdmin/
If we are using PmaAbsoluteUri
auto-detection, shown as follows:
$cfg['PmaAbsoluteUri'] = '';
phpMyAdmin will see that we are using HTTPS in the URL and react accordingly.
If not, we must put the https
part in this parameter as follows:
$cfg['PmaAbsoluteUri'] = 'https://www.mydomain.com/phpMyAdmin';
We can automatically switch users to an HTTPS connection with the following setting:
$cfg['ForceSSL'] = TRUE;
18.117.142.144