From 4bf8bfcaa16dd90d7b36c2c3f5e2d36c7b249bd2 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Wed, 12 Jun 2019 10:43:15 +0200 Subject: [PATCH] Fix broken foreign key links Fixes: #15225 - Using Command+Click to open in new tab does not work (Firefox/Safari) Fixes: #14270 - Middle-click on foreign key link broken Fixes: #14363 - Broken relational links in tables Signed-off-by: William Desportes --- libraries/classes/Core.php | 24 ++++++++++++++++++++++++ libraries/classes/Display/Results.php | 15 +++++++++------ libraries/classes/Util.php | 3 ++- sql.php | 5 +++++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/libraries/classes/Core.php b/libraries/classes/Core.php index 447b951daa..50e1a58744 100644 --- a/libraries/classes/Core.php +++ b/libraries/classes/Core.php @@ -1289,4 +1289,28 @@ class Core self::fatalError(__('possible exploit')); } } + + /** + * Sign the sql query using hmac using the session token + * + * @param string $sqlQuery The sql query + * @return void + */ + public static function signSqlQuery(string $sqlQuery) + { + return hash_hmac('sha256', $sqlQuery, $_SESSION[' PMA_token ']); + } + + /** + * Check that the sql query has a valid hmac signature + * + * @param string $sqlQuery The sql query + * @return void + */ + public static function checkSqlQuerySignature(string $sqlQuery, string $signature) + { + $hmac = hash_hmac('sha256', $sqlQuery, $_SESSION[' PMA_token ']); + return hash_equals($hmac, $signature); + } + } diff --git a/libraries/classes/Display/Results.php b/libraries/classes/Display/Results.php index 87d0879b5f..cde874aee5 100644 --- a/libraries/classes/Display/Results.php +++ b/libraries/classes/Display/Results.php @@ -5313,16 +5313,19 @@ class Results $title = htmlspecialchars($data); } + $sqlQuery = 'SELECT * FROM ' + . Util::backquote($map[$meta->name][3]) . '.' + . Util::backquote($map[$meta->name][0]) + . ' WHERE ' + . Util::backquote($map[$meta->name][1]) + . $where_comparison; + $_url_params = array( 'db' => $map[$meta->name][3], 'table' => $map[$meta->name][0], 'pos' => '0', - 'sql_query' => 'SELECT * FROM ' - . Util::backquote($map[$meta->name][3]) . '.' - . Util::backquote($map[$meta->name][0]) - . ' WHERE ' - . Util::backquote($map[$meta->name][1]) - . $where_comparison, + 'sql_signature' => Core::signSqlQuery($sqlQuery), + 'sql_query' => $sqlQuery, ); if ($transformation_plugin != $default_function) { diff --git a/libraries/classes/Util.php b/libraries/classes/Util.php index a3f08ad4ec..c64a709444 100644 --- a/libraries/classes/Util.php +++ b/libraries/classes/Util.php @@ -1760,7 +1760,8 @@ class Util $tag_params_strings = array(); if (($url_length > $GLOBALS['cfg']['LinkLengthLimit']) || ! $in_suhosin_limits - || strpos($url, 'sql_query=') !== false + // Has as sql_query without a signature + || ( strpos($url, 'sql_query=') !== false && strpos($url, 'sql_signature=') === false) || strpos($url, 'view[as]=') !== false ) { $parts = explode('?', $url, 2); diff --git a/sql.php b/sql.php index 5e73353519..8a5c2cd755 100644 --- a/sql.php +++ b/sql.php @@ -13,6 +13,7 @@ use PhpMyAdmin\Response; use PhpMyAdmin\Sql; use PhpMyAdmin\Url; use PhpMyAdmin\Util; +use PhpMyAdmin\Core; /** * Gets some core libraries @@ -71,6 +72,10 @@ if (isset($_POST['bkm_fields']['bkm_sql_query'])) { $sql_query = $_POST['bkm_fields']['bkm_sql_query']; } elseif (isset($_POST['sql_query'])) { $sql_query = $_POST['sql_query']; +} elseif (isset($_GET['sql_query']) && isset($_GET['sql_signature'])) { + if (Core::checkSqlQuerySignature($_GET['sql_query'], $_GET['sql_signature'])) { + $sql_query = $_GET['sql_query']; + } } // This one is just to fill $db