Skip to content

Commit

Permalink
Security fix: Replace all calls to unserialize() with calls to phpMyA…
Browse files Browse the repository at this point in the history
…dmin's safeUnserialize wrapper.
  • Loading branch information
ReimuHakurei committed Aug 5, 2023
1 parent 480fa9e commit bcedd68
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 34 deletions.
8 changes: 4 additions & 4 deletions admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function doCluster($type, $confirm=false) {

echo "<form action=\"{$script}\" method=\"post\">\n";
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfclustertable'], $misc->printVal($a['table'])), "</p>\n";
echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n";
}
Expand Down Expand Up @@ -103,7 +103,7 @@ function doReindex($type, $confirm=false) {

echo "<form action=\"{$script}\" method=\"post\">\n";
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfreindextable'], $misc->printVal($a['table'])), "</p>\n";
echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n";
}
Expand Down Expand Up @@ -181,7 +181,7 @@ function doAnalyze($type, $confirm=false) {

echo "<form action=\"{$script}\" method=\"post\">\n";
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfanalyzetable'], $misc->printVal($a['table'])), "</p>\n";
echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n";
}
Expand Down Expand Up @@ -256,7 +256,7 @@ function doVacuum($type, $confirm = false) {

echo "<form action=\"{$script}\" method=\"post\">\n";
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfvacuumtable'], $misc->printVal($a['table'])), "</p>\n";
echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n";
}
Expand Down
2 changes: 1 addition & 1 deletion all_db.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function doDrop($confirm) {
// If multi drop
if (isset($_REQUEST['ma'])) {
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfdropdatabase'], $misc->printVal($a['database'])), "</p>\n";
printf('<input type="hidden" name="dropdatabase[]" value="%s" />', htmlspecialchars($a['database']));
}
Expand Down
8 changes: 4 additions & 4 deletions constraints.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function addForeignKey($stage, $msg = '') {
if (!isset($_POST['match'])) $_POST['match'] = null;
if (!isset($_POST['deferrable'])) $_POST['deferrable'] = null;
if (!isset($_POST['initially'])) $_POST['initially'] = null;
$_REQUEST['target'] = unserialize($_REQUEST['target']);
$_REQUEST['target'] = safeUnserialize($_REQUEST['target']);

$misc->printTrail('table');
$misc->printTitle($lang['straddfk'],'pg.constraint.foreign_key');
Expand Down Expand Up @@ -129,16 +129,16 @@ function addForeignKey($stage, $msg = '') {
break;
case 3:
// Unserialize target
$_POST['target'] = unserialize($_POST['target']);
$_POST['target'] = safeUnserialize($_POST['target']);

// Check that they've given at least one column
if (isset($_POST['SourceColumnList'])) $temp = unserialize($_POST['SourceColumnList']);
if (isset($_POST['SourceColumnList'])) $temp = safeUnserialize($_POST['SourceColumnList']);
if (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList'])
|| sizeof($_POST['IndexColumnList']) == 0 || !isset($temp)
|| !is_array($temp) || sizeof($temp) == 0) addForeignKey(2, $lang['strfkneedscols']);
else {
$status = $data->addForeignKey($_POST['table'], $_POST['target']['schemaname'], $_POST['target']['tablename'],
unserialize($_POST['SourceColumnList']), $_POST['IndexColumnList'], $_POST['upd_action'], $_POST['del_action'],
safeUnserialize($_POST['SourceColumnList']), $_POST['IndexColumnList'], $_POST['upd_action'], $_POST['del_action'],
$_POST['match'], $_POST['deferrable'], $_POST['initially'], $_POST['name']);
if ($status == 0)
doDefault($lang['strfkadded']);
Expand Down
4 changes: 2 additions & 2 deletions display.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function doEditRow($confirm, $msg = '') {
if (is_array($_REQUEST['key']))
$key = $_REQUEST['key'];
else
$key = unserialize(urldecode($_REQUEST['key']));
$key = safeUnserialize(urldecode($_REQUEST['key']));

if ($confirm) {
$misc->printTrail($_REQUEST['subject']);
Expand Down Expand Up @@ -238,7 +238,7 @@ function doDelRow($confirm) {
echo "</form>\n";
}
else {
$status = $data->deleteRow($_POST['table'], unserialize(urldecode($_POST['key'])));
$status = $data->deleteRow($_POST['table'], safeUnserialize(urldecode($_POST['key'])));
if ($status == 0)
doBrowse($lang['strrowdeleted']);
elseif ($status == -2)
Expand Down
10 changes: 5 additions & 5 deletions fulltext.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,9 @@ function doSaveCreateConfig() {

if ($err != '') return doCreateConfig($err);

if ($_POST['formParser'] != '') $formParser = unserialize($_POST['formParser']);
if ($_POST['formParser'] != '') $formParser = safeUnserialize($_POST['formParser']);
else $formParser = '';
if ($_POST['formTemplate'] != '') $formTemplate = unserialize($_POST['formTemplate']);
if ($_POST['formTemplate'] != '') $formTemplate = safeUnserialize($_POST['formTemplate']);
else $formTemplate = '';

$status = $data->createFtsConfiguration($_POST['formName'], $formParser, $formTemplate, $_POST['formComment']);
Expand Down Expand Up @@ -667,7 +667,7 @@ function doSaveCreateDict() {

if(!isset($_POST['formIsTemplate'])) $_POST['formIsTemplate'] = false;
if(isset($_POST['formTemplate']))
$formTemplate = unserialize($_POST['formTemplate']);
$formTemplate = safeUnserialize($_POST['formTemplate']);
else
$formTemplate = '';
if(!isset($_POST['formLexize'])) $_POST['formLexize'] = '';
Expand Down Expand Up @@ -773,7 +773,7 @@ function doDropMapping($confirm) {
if (isset($_REQUEST['ma'])) {

foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfdropftsmapping'], $misc->printVal($a['mapping']), $misc->printVal($_REQUEST['ftscfg'])), "</p>\n";
printf('<input type="hidden" name="mapping[]" value="%s" />', htmlspecialchars($a['mapping']));
}
Expand Down Expand Up @@ -835,7 +835,7 @@ function doAlterMapping($msg = '') {
$ma_mappings = array();
$ma_mappings_names = array();
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
printf('<input type="hidden" name="formMapping[]" value="%s" />', htmlspecialchars($a['mapping']));
$ma_mappings[] = $data->getFtsMappingByName($_POST['ftscfg'], $a['mapping']);
$ma_mappings_names[] = $a['mapping'];
Expand Down
2 changes: 1 addition & 1 deletion functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ function doDrop($confirm) {
//If multi drop
if (isset($_REQUEST['ma'])) {
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfdropfunction'], $misc->printVal($a['function'])), "</p>\n";
echo '<input type="hidden" name="function[]" value="', htmlspecialchars($a['function']), "\" />\n";
echo "<input type=\"hidden\" name=\"function_oid[]\" value=\"", htmlspecialchars($a['function_oid']), "\" />\n";
Expand Down
90 changes: 90 additions & 0 deletions libraries/lib.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,93 @@
}

$plugin_manager = new PluginManager($_language);

/**
* Safe unserializer wrapper
*
* It does not unserialize data containing objects
*
* Function from phpMyAdmin version 5.2.1
*
* @param string $data Data to unserialize
*
* @return mixed|null
*/
function safeUnserialize(string $data) {
/* 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(substr($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 separator
$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);
}
2 changes: 1 addition & 1 deletion schemas.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ function doDrop($confirm) {
//If multi drop
if (isset($_REQUEST['ma'])) {
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo '<p>', sprintf($lang['strconfdropschema'], $misc->printVal($a['nsp'])), "</p>\n";
echo '<input type="hidden" name="nsp[]" value="', htmlspecialchars($a['nsp']), "\" />\n";
}
Expand Down
8 changes: 4 additions & 4 deletions sequences.php
Original file line number Diff line number Diff line change
Expand Up @@ -297,18 +297,18 @@ function doDrop($confirm, $msg = '') {
doDefault($lang['strspecifysequencetodrop']);
exit();
}

if ($confirm) {
$misc->printTrail('sequence');
$misc->printTitle($lang['strdrop'],'pg.sequence.drop');
$misc->printMsg($msg);

echo "<form action=\"sequences.php\" method=\"post\">\n";

//If multi drop
if (isset($_REQUEST['ma'])) {
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfdropsequence'], $misc->printVal($a['sequence'])), "</p>\n";
printf('<input type="hidden" name="sequence[]" value="%s" />', htmlspecialchars($a['sequence']));
}
Expand Down
8 changes: 4 additions & 4 deletions tables.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ function doCreateLike($confirm, $msg = '') {

if (!isset($_REQUEST['tablespace'])) $_REQUEST['tablespace'] = '';

$status = $data->createTableLike($_REQUEST['name'], unserialize($_REQUEST['like']), isset($_REQUEST['withdefaults']),
$status = $data->createTableLike($_REQUEST['name'], safeUnserialize($_REQUEST['like']), isset($_REQUEST['withdefaults']),
isset($_REQUEST['withconstraints']), isset($_REQUEST['withindexes']), $_REQUEST['tablespace']);

if ($status == 0) {
Expand Down Expand Up @@ -563,7 +563,7 @@ function doInsertRow($confirm, $msg = '') {
else {
if (!isset($_POST['values'])) $_POST['values'] = array();
if (!isset($_POST['nulls'])) $_POST['nulls'] = array();
$_POST['fields'] = unserialize(htmlspecialchars_decode($_POST['fields'], ENT_QUOTES));
$_POST['fields'] = safeUnserialize(htmlspecialchars_decode($_POST['fields'], ENT_QUOTES));

if ($_SESSION['counter']++ == $_POST['protection_counter']) {
$status = $data->insertRow($_POST['table'], $_POST['fields'], $_POST['values'],
Expand Down Expand Up @@ -604,7 +604,7 @@ function doEmpty($confirm) {

echo "<form action=\"tables.php\" method=\"post\">\n";
foreach ($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfemptytable'], $misc->printVal($a['table'])), "</p>\n";
printf('<input type="hidden" name="table[]" value="%s" />', htmlspecialchars($a['table']));
}
Expand Down Expand Up @@ -669,7 +669,7 @@ function doDrop($confirm) {

echo "<form action=\"tables.php\" method=\"post\">\n";
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfdroptable'], $misc->printVal($a['table'])), "</p>\n";
printf('<input type="hidden" name="table[]" value="%s" />', htmlspecialchars($a['table']));
}
Expand Down
16 changes: 8 additions & 8 deletions views.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ function doDrop($confirm) {
//If multi drop
if (isset($_REQUEST['ma'])) {
foreach($_REQUEST['ma'] as $v) {
$a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
$a = safeUnserialize(htmlspecialchars_decode($v, ENT_QUOTES));
echo "<p>", sprintf($lang['strconfdropview'], $misc->printVal($a['view'])), "</p>\n";
echo '<input type="hidden" name="view[]" value="', htmlspecialchars($a['view']), "\" />\n";
}
Expand Down Expand Up @@ -214,9 +214,9 @@ function doSetParamsCreate($msg = '') {
$misc->printMsg($msg);

$tblCount = sizeof($_POST['formTables']);
//unserialize our schema/table information and store in arrSelTables
// Unserialize our schema/table information and store in arrSelTables
for ($i = 0; $i < $tblCount; $i++) {
$arrSelTables[] = unserialize($_POST['formTables'][$i]);
$arrSelTables[] = safeUnserialize($_POST['formTables'][$i]);
}

$linkCount = $tblCount;
Expand Down Expand Up @@ -446,7 +446,7 @@ function doSaveCreateWiz() {
$tmpHsh = array();

foreach ($_POST['formFields'] as $curField) {
$arrTmp = unserialize($curField);
$arrTmp = safeUnserialize($curField);
$data->fieldArrayClean($arrTmp);
if (! empty($_POST['dblFldMeth']) ) { // doublon control
if (empty($tmpHsh[$arrTmp['fieldname']])) { // field does not exist
Expand Down Expand Up @@ -486,8 +486,8 @@ function doSaveCreateWiz() {
while ($j < $count) {
foreach ($arrLinks as $curLink) {

$arrLeftLink = unserialize($curLink['leftlink']);
$arrRightLink = unserialize($curLink['rightlink']);
$arrLeftLink = safeUnserialize($curLink['leftlink']);
$arrRightLink = safeUnserialize($curLink['rightlink']);
$data->fieldArrayClean($arrLeftLink);
$data->fieldArrayClean($arrRightLink);

Expand Down Expand Up @@ -517,7 +517,7 @@ function doSaveCreateWiz() {
//just select from all selected tables - a cartesian join do a
if (!strlen($linkFields) ) {
foreach ($_POST['formTables'] as $curTable) {
$arrTmp = unserialize($curTable);
$arrTmp = safeUnserialize($curTable);
$data->fieldArrayClean($arrTmp);
$linkFields .= strlen($linkFields) ? ", \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\"" : "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\"";
}
Expand All @@ -527,7 +527,7 @@ function doSaveCreateWiz() {
if (is_array($_POST['formCondition']) ) {
foreach ($_POST['formCondition'] as $curCondition) {
if (strlen($curCondition['field']) && strlen($curCondition['txt']) ) {
$arrTmp = unserialize($curCondition['field']);
$arrTmp = safeUnserialize($curCondition['field']);
$data->fieldArrayClean($arrTmp);
$addConditions .= strlen($addConditions) ? " AND \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' "
: " \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' ";
Expand Down

0 comments on commit bcedd68

Please sign in to comment.