|
@@ -102,6 +102,22 @@ abstract class xPDOQuery extends xPDOCriteria { |
|
|
|
'limit' => '', |
|
|
|
); |
|
|
|
|
|
|
|
/** |
|
|
|
* Make sure a clause is valid and does not contain SQL injection attempts. |
|
|
|
* |
|
|
|
* @param string $clause The string clause to validate. |
|
|
|
* |
|
|
|
* @return bool True if the clause is valid. |
|
|
|
*/ |
|
|
|
public static function isValidClause($clause) { |
|
|
|
$output = rtrim($clause, ' ;'); |
|
|
|
$output = preg_replace("/\\\\'.*?\\\\'/", '{mask}', $output); |
|
|
|
$output = preg_replace('/\\".*?\\"/', '{mask}', $output); |
|
|
|
$output = preg_replace("/'.*?'/", '{mask}', $output); |
|
|
|
$output = preg_replace('/".*?"/', '{mask}', $output); |
|
|
|
return strpos($output, ';') === false && strpos(strtolower($output), 'union') === false; |
|
|
|
} |
|
|
|
|
|
|
|
public function __construct(& $xpdo, $class, $criteria= null) { |
|
|
|
parent :: __construct($xpdo); |
|
|
|
if ($class= $this->xpdo->loadClass($class)) { |
|
@@ -404,7 +420,7 @@ public function sortby($column, $direction= 'ASC') { |
|
|
|
$direction = ''; |
|
|
|
} |
|
|
|
|
|
|
|
if (!$this->isValidClause($column)) { |
|
|
|
if (!static::isValidClause($column)) { |
|
|
|
$this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'SQL injection attempt detected in sortby column; clause rejected'); |
|
|
|
} elseif (!empty($column)) { |
|
|
|
$this->query['sortby'][] = array('column' => $column, 'direction' => $direction); |
|
@@ -777,7 +793,7 @@ public function parseConditions($conditions, $conjunction = xPDOQuery::SQL_AND) |
|
|
|
,'conjunction' => $conjunction |
|
|
|
)); |
|
|
|
} |
|
|
|
elseif (($pktype == 'integer' && is_numeric($conditions)) || ($pktype == 'string' && is_string($conditions) && $this->isValidClause($conditions))) { |
|
|
|
elseif (($pktype == 'integer' && is_numeric($conditions)) || ($pktype == 'string' && is_string($conditions) && static::isValidClause($conditions))) { |
|
|
|
if ($pktype == 'integer') { |
|
|
|
$param_type= PDO::PARAM_INT; |
|
|
|
} else { |
|
@@ -795,12 +811,14 @@ public function parseConditions($conditions, $conjunction = xPDOQuery::SQL_AND) |
|
|
|
* Determines if a string contains a conditional operator. |
|
|
|
* |
|
|
|
* @param string $string The string to evaluate. |
|
|
|
* @return boolean True if the string is a complete conditional SQL clause. |
|
|
|
* |
|
|
|
* @return bool True if the string is a complete conditional SQL clause. |
|
|
|
* @throws xPDOException If a SQL injection attempt is detected. |
|
|
|
*/ |
|
|
|
public function isConditionalClause($string) { |
|
|
|
$matched= false; |
|
|
|
if (is_string($string)) { |
|
|
|
if (!$this->isValidClause($string)) { |
|
|
|
if (!static::isValidClause($string)) { |
|
|
|
throw new xPDOException("SQL injection attempt detected: {$string}"); |
|
|
|
} |
|
|
|
foreach ($this->_operators as $operator) { |
|
@@ -813,15 +831,6 @@ public function isConditionalClause($string) { |
|
|
|
return $matched; |
|
|
|
} |
|
|
|
|
|
|
|
public function isValidClause($clause) { |
|
|
|
$output = rtrim($clause, ' ;'); |
|
|
|
$output = preg_replace("/\\\\'.*?\\\\'/", '{mask}', $output); |
|
|
|
$output = preg_replace('/\\".*?\\"/', '{mask}', $output); |
|
|
|
$output = preg_replace("/'.*?'/", '{mask}', $output); |
|
|
|
$output = preg_replace('/".*?"/', '{mask}', $output); |
|
|
|
return strpos($output, ';') === false && strpos(strtolower($output), 'union') === false; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Builds conditional clauses from xPDO condition expressions. |
|
|
|
* |
|
|
0 comments on commit
305f2ba