Skip to content

Commit

Permalink
DataSet : Better validate formula column. (#2631)
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterMis authored Jul 15, 2024
1 parent 0c8afc8 commit 6b549e8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
20 changes: 17 additions & 3 deletions lib/Entity/DataSet.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
* Copyright (C) 2024 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
Expand Down Expand Up @@ -526,7 +526,21 @@ public function getData($filterBy = [], $options = [], $extraParams = [])
continue;
}

$formula = str_ireplace($this->blackList, '', htmlspecialchars_decode($column->formula, ENT_QUOTES));
$count = 0;
$formula = str_ireplace(
$this->blackList,
'',
htmlspecialchars_decode($column->formula, ENT_QUOTES),
$count
);

if ($count > 0) {
$this->getLog()->error(
'Formula contains disallowed keywords on DataSet ID ' . $this->dataSetId
);
continue;
}

$formula = str_replace('[DisplayId]', $displayId, $formula);

$heading = str_replace('[DisplayGeoLocation]', $displayGeoLocation, $formula) . ' AS `' . $column->heading . '`';
Expand Down
19 changes: 17 additions & 2 deletions lib/Entity/DataSetColumn.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/*
* Copyright (C) 2023 Xibo Signage Ltd
* Copyright (C) 2024 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
Expand Down Expand Up @@ -146,6 +146,9 @@ class DataSetColumn implements \JsonSerializable
/** @var DataSetColumnTypeFactory */
private $dataSetColumnTypeFactory;

/** @var array Blacklist for SQL */
private $blackList = [';', 'INSERT', 'UPDATE', 'SELECT', 'DELETE', 'TRUNCATE', 'TABLE', 'FROM', 'WHERE'];

/**
* The prior dataset column id, when cloning
* @var int
Expand Down Expand Up @@ -278,7 +281,19 @@ public function validate()
// if formula dataSetType is set and formula is not empty, try to execute the SQL to validate it - we're ignoring client side formulas here.
if ($this->dataSetColumnTypeId == 2 && $this->formula != '' && substr($this->formula, 0, 1) !== '$') {
try {
$formula = str_replace('[DisplayId]', 0, $this->formula);
$count = 0;
$formula = str_ireplace(
$this->blackList,
'',
htmlspecialchars_decode($this->formula, ENT_QUOTES),
$count
);

if ($count > 0) {
throw new InvalidArgumentException(__('Formula contains disallowed keywords.'));
}

$formula = str_replace('[DisplayId]', 0, $formula);
// replace DisplayGeoLocation with default CMS location, just to validate here.
$formula = str_replace('[DisplayGeoLocation]', "GEOMFROMTEXT('POINT(51.504 -0.104)')", $formula);
$this->getStore()->select('SELECT * FROM (SELECT `id`, ' . $formula . ' AS `' . $this->heading . '` FROM `dataset_' . $this->dataSetId . '`) dataset WHERE 1 = 1 ', [], 'isolated');
Expand Down

0 comments on commit 6b549e8

Please sign in to comment.