SQL-Injection vulnerability in GET function resolved.

This commit is contained in:
2026-06-13 23:17:12 +02:00
parent 9de2fc0ad1
commit c408e43283

View File

@@ -4,6 +4,7 @@ namespace api\classes;
class API class API
{ {
public $conn; public $conn;
public $pdo;
# The user uuid that requested the API # The user uuid that requested the API
protected $user_uuid; protected $user_uuid;
@@ -42,14 +43,21 @@ class API
# Used for the query builder base # Used for the query builder base
public $baseQuery = false; public $baseQuery = false;
# Used for the general get function, this prevents SQL injecting by only allowing these columns instead of
# Whatever the user inputs straigt into the query.
public $allowedGetColumns = false;
# Cache the columns of the tables for some small performance improvements.
private static array $columnCache = [];
public function __construct() public function __construct()
{ {
require_once $_SERVER['DOCUMENT_ROOT'] . '/bin/php/db_connect.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/bin/php/db_connect.php';
include_once $_SERVER['DOCUMENT_ROOT'] . '/bin/php/Functions/globalFunctions.php'; include_once $_SERVER['DOCUMENT_ROOT'] . '/bin/php/Functions/globalFunctions.php';
# Setup Database connection # Setup Database connection
$this->conn = $GLOBALS['conn']; $this->conn = $GLOBALS['conn'];
$this->pdo = $GLOBALS['pdo'];
if (!empty($_SESSION['user']['user_uuid'])) { if (!empty($_SESSION['user']['user_uuid'])) {
$this->InitUserTypeFrontend(); $this->InitUserTypeFrontend();
@@ -694,6 +702,8 @@ class API
protected function buildDynamicQuery(string $tableName): array protected function buildDynamicQuery(string $tableName): array
{ {
$this->allowedGetColumns = $this->loadTableColumns($tableName);
if (!$this->baseQuery) { if (!$this->baseQuery) {
$this->baseQuery = "SELECT * FROM " . $tableName; $this->baseQuery = "SELECT * FROM " . $tableName;
} }
@@ -714,6 +724,10 @@ class API
$column = $builder['where'][0]; $column = $builder['where'][0];
$value = $builder['where'][1]; $value = $builder['where'][1];
if (!in_array($column, $this->allowedGetColumns, true)) {
$this->apiOutput(400, ['error' => 'The column ' . $column . ' is not allowed.']);
}
$whereClauses[] = "$column = ?"; $whereClauses[] = "$column = ?";
$types .= 's'; $types .= 's';
$values[] = $value; $values[] = $value;
@@ -726,6 +740,20 @@ class API
return [$this->baseQuery, $types, $values]; return [$this->baseQuery, $types, $values];
} }
protected function loadTableColumns(string $tableName): array
{
if (isset(self::$columnCache[$tableName])) {
return self::$columnCache[$tableName];
}
$sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$tableName]);
return self::$columnCache[$tableName] = $stmt->fetchAll(\PDO::FETCH_COLUMN);
}
protected function generalGetFunction($query, $types, $params, $returnBoolean, $itemName) protected function generalGetFunction($query, $types, $params, $returnBoolean, $itemName)
{ {
$stmt = $this->prepareStatement($query); $stmt = $this->prepareStatement($query);