Skip to content

Commit

Permalink
Prevent SQL injection on DbUtils::getDateCriteria()
Browse files Browse the repository at this point in the history
  • Loading branch information
cedric-anne authored and trasher committed Apr 5, 2023
1 parent 53f2674 commit 3b1f593
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
20 changes: 17 additions & 3 deletions src/DbUtils.php
Expand Up @@ -1913,16 +1913,30 @@ public function closeDBConnections()
*/
public function getDateCriteria($field, $begin, $end)
{
global $DB;

$date_pattern = '/^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2})?$/'; // `YYYY-mm-dd` optionaly followed by ` HH:ii:ss`

$criteria = [];
if (!empty($begin)) {
if (is_string($begin) && preg_match($date_pattern, $begin) === 1) {
$criteria[] = [$field => ['>=', $begin]];
} elseif ($begin !== null && $begin !== '') {
trigger_error(
sprintf('Invalid %s date value.', json_encode($begin)),
E_USER_WARNING
);
}

if (!empty($end)) {
if (is_string($end) && preg_match($date_pattern, $end) === 1) {
$end_expr = new QueryExpression(
'ADDDATE(\'' . $end . '\', INTERVAL 1 DAY)'
'ADDDATE(' . $DB->quoteValue($end) . ', INTERVAL 1 DAY)'
);
$criteria[] = [$field => ['<=', $end_expr]];
} elseif ($end !== null && $end !== '') {
trigger_error(
sprintf('Invalid %s date value.', json_encode($end)),
E_USER_WARNING
);
}

return $criteria;
Expand Down
34 changes: 28 additions & 6 deletions tests/functional/DbUtils.php
Expand Up @@ -1281,6 +1281,10 @@ public function testGetDateCriteria()
$this->testedInstance->getDateCriteria('date', null, null)
)->isIdenticalTo([]);

$this->array(
$this->testedInstance->getDateCriteria('date', '', '')
)->isIdenticalTo([]);

$this->array(
$this->testedInstance->getDateCriteria('date', '2018-11-09', null)
)->isIdenticalTo([
Expand All @@ -1291,9 +1295,9 @@ public function testGetDateCriteria()
$this->array($result)->hasSize(1);

$this->array($result[0]['date'])
->hasSize(2)
->string[0]->isIdenticalTo('<=')
->object[1]->isInstanceOf('\QueryExpression');
->hasSize(2)
->string[0]->isIdenticalTo('<=')
->object[1]->isInstanceOf('\QueryExpression');

$this->string(
$result[0]['date'][1]->getValue()
Expand All @@ -1304,13 +1308,31 @@ public function testGetDateCriteria()

$this->array($result[0])->isIdenticalTo(['date' => ['>=', '2018-11-08']]);
$this->array($result[1]['date'])
->hasSize(2)
->string[0]->isIdenticalTo('<=')
->object[1]->isInstanceOf('\QueryExpression');
->hasSize(2)
->string[0]->isIdenticalTo('<=')
->object[1]->isInstanceOf('\QueryExpression');

$this->string(
$result[1]['date'][1]->getValue()
)->isIdenticalTo("ADDDATE('2018-11-09', INTERVAL 1 DAY)");

$result = null;
$this->when(function () use (&$result) {
$result = $this->testedInstance->getDateCriteria('date', '2023-02-19\', INTERVAL 1 DAY)))))', null);
})->error
->withType(E_USER_WARNING)
->withMessage('Invalid "2023-02-19\', INTERVAL 1 DAY)))))" date value.')
->exists();
$this->array($result)->isIdenticalTo([]);

$result = null;
$this->when(function () use (&$result) {
$result = $this->testedInstance->getDateCriteria('date', null, '2021-02-19\', INTERVAL 1 DAY)))))');
})->error
->withType(E_USER_WARNING)
->withMessage('Invalid "2021-02-19\', INTERVAL 1 DAY)))))" date value.')
->exists();
$this->array($result)->isIdenticalTo([]);
}

protected function autoNameProvider()
Expand Down

0 comments on commit 3b1f593

Please sign in to comment.