From 00f115064342404cd372913226d694c8425c00c6 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Thu, 21 Apr 2016 00:44:27 +0200 Subject: [PATCH] Minimal check to validate relationship params. --- CRM/Contact/Page/AJAX.php | 18 +------------- CRM/Core/Page/AJAX.php | 24 ++++++++++++++++++ CRM/Utils/Rule.php | 51 +++++++++++++++++++++++++++++++++++++++ CRM/Utils/Type.php | 18 ++++++++++++++ 4 files changed, 94 insertions(+), 17 deletions(-) diff --git a/CRM/Contact/Page/AJAX.php b/CRM/Contact/Page/AJAX.php index 14336ac4d7..cd97123088 100644 --- a/CRM/Contact/Page/AJAX.php +++ b/CRM/Contact/Page/AJAX.php @@ -1019,23 +1019,7 @@ LIMIT {$offset}, {$rowCount} return CRM_Utils_System::permissionDenied(); } - $sortMapper = array(); - foreach ($_GET['columns'] as $key => $value) { - $sortMapper[$key] = $value['data']; - }; - - $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : 0; - $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : 25; - $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : NULL; - $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'String') : 'asc'; - - $params = $_GET; - if ($sort && $sortOrder) { - $params['sortBy'] = $sort . ' ' . $sortOrder; - } - - $params['page'] = ($offset / $rowCount) + 1; - $params['rp'] = $rowCount; + $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams(); $params['contact_id'] = $contactID; $params['context'] = $context; diff --git a/CRM/Core/Page/AJAX.php b/CRM/Core/Page/AJAX.php index 09ca9d0cf1..9777e8f5d1 100644 --- a/CRM/Core/Page/AJAX.php +++ b/CRM/Core/Page/AJAX.php @@ -214,4 +214,28 @@ class CRM_Core_Page_AJAX { CRM_Utils_System::setHttpHeader('Cache-Control', "max-age=$ttl, public"); } + public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRowCount = 25, $defaultSort = NULL, $defaultsortOrder = 'asc') { + $params = array(); + + $sortMapper = array(); + foreach ($_GET['columns'] as $key => $value) { + $sortMapper[$key] = CRM_Utils_Type::escape($value['data'], 'MysqlColumnName'); + }; + + $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : $defaultOffset; + $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : $defaultRowCount; + // Why is the number of order by columns limited to 1? + $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : $defaultSort; + $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'MysqlOrderByDirection') : $defaultsortOrder; + + if ($sort) { + $params['sortBy'] = "`{$sort}` {$sortOrder}"; + } + + $params['page'] = ($offset / $rowCount) + 1; + $params['rp'] = $rowCount; + + return $params; + } + } diff --git a/CRM/Utils/Rule.php b/CRM/Utils/Rule.php index 97153c51db..d73785fdba 100644 --- a/CRM/Utils/Rule.php +++ b/CRM/Utils/Rule.php @@ -87,6 +87,57 @@ class CRM_Utils_Rule { return TRUE; } + /** + * @param $str + * + * @return bool + */ + public static function MysqlColumnName($str) { + // check the length. + // This check can be incorrect for the . format, which can be + // a problem. + if (empty($str) || strlen($str) > 64) { + return FALSE; + } + + return TRUE; + } + + /** + * @param $str + * + * @return bool + */ + public static function MysqlColumnNameStrict($str) { + // check the length. + if (empty($str) || strlen($str) > 64) { + return FALSE; + } + + // make sure it only contains valid characters (alphanumeric and underscores) + // This check doesn't support the
. format, which can be + // a problem. + // @todo : check with the standards (http://dev.mysql.com/doc/refman/5.5/en/identifiers.html) + if (!preg_match('/^[\w_]+$/i', $str)) { + return FALSE; + } + + return TRUE; + } + + /** + * @param $str + * + * @return bool + */ + public static function MysqlOrderByDirection($str) { + if (!preg_match('/^(asc|desc)$/i', $str)) { + return FALSE; + } + + return TRUE; + } + /** * @param $str * diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index a7816f7dd2..fca08b7e5d 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -256,6 +256,24 @@ class CRM_Utils_Type { } break; + case 'MysqlColumnName': + if (CRM_Utils_Rule::MysqlColumnName($data)) { + return str_replace('`', '', $data); + } + break; + + case 'MysqlColumnNameStrict': + if (CRM_Utils_Rule::MysqlColumnNameStrict($data)) { + return $data; + } + break; + + case 'MysqlOrderByDirection': + if (CRM_Utils_Rule::MysqlOrderByDirection($data)) { + return $data; + } + break; + default: CRM_Core_Error::fatal( $type . " is not a recognised (camel cased) data type." -- 2.25.1