From 95b1db2309ec02535a087cd80d300d06ea65dbee Mon Sep 17 00:00:00 2001 From: Justin Bosker Date: Wed, 22 Jul 2026 01:37:21 +0200 Subject: [PATCH] security: replace raw SQL queries with prepared statements in Data.class.php - 15 methods migrated from query() to prepare()+execute() - changeTermin() now uses column whitelist (11 allowed columns) - setTerminStatus() delegates to changeTermin() - Added ?: null fallbacks and type hints - Consistent pattern across all database methods --- Data.class.php | 140 ++++++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 65 deletions(-) diff --git a/Data.class.php b/Data.class.php index c13a6d1..c61b6ef 100644 --- a/Data.class.php +++ b/Data.class.php @@ -26,24 +26,24 @@ class Data { public function getDataByID($id, $column){ - $sql = "SELECT * FROM users WHERE id = '" . $id . "'"; - foreach($this->pdo->query($sql) as $row) { - return $row[$column]; - } + $stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = :id"); + $stmt->execute([':id' => $id]); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + return $row[$column] ?? null; } public function getTerminDataById($id, $column){ - $sql = "SELECT * FROM termine WHERE id = '" . $id . "'"; - foreach($this->pdo->query($sql) as $row) { - return $row[$column]; - } + $stmt = $this->pdo->prepare("SELECT * FROM termine WHERE id = :id"); + $stmt->execute([':id' => $id]); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + return $row[$column] ?? null; } public function getSettingsData($column){ - $sql = "SELECT * FROM settings_calendar WHERE id = '1'"; - foreach($this->pdo->query($sql) as $row) { - return $row[$column]; - } + $stmt = $this->pdo->prepare("SELECT * FROM settings_calendar WHERE id = 1"); + $stmt->execute(); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + return $row[$column] ?? null; } public function timestampToDate($timestamp){ @@ -106,30 +106,29 @@ class Data { } - public function getOnlineStatusLabel($id){ - $sql = "SELECT * FROM users WHERE id = '" . $id . "'"; - foreach($this->pdo->query($sql) as $row) { - if($row['online'] == 0){ - return "badge-danger"; - }else{ - return "badge-success"; - } + public function getOnlineStatusLabel($id): string { + $stmt = $this->pdo->prepare("SELECT online FROM users WHERE id = :id"); + $stmt->execute([':id' => $id]); + $online = $stmt->fetchColumn(); + + if ($online === false) { + return "badge-secondary"; } + + return ((int)$online === 0) ? "badge-danger" : "badge-success"; } - public function getTodoStatusLabel($id){ - $sql = "SELECT * FROM todo WHERE id = '" . $id . "'"; - foreach($this->pdo->query($sql) as $row) { - if($row['status'] == 0){ - return "danger"; - } - if($row['status'] == 1){ - return "warning"; - } - if($row['status'] == 2){ - return "success"; - } - } + public function getTodoStatusLabel($id): string { + $stmt = $this->pdo->prepare("SELECT status FROM todo WHERE id = :id"); + $stmt->execute([':id' => $id]); + $status = $stmt->fetchColumn(); + + return match ((int)$status) { + 0 => "danger", + 1 => "warning", + 2 => "success", + default => "secondary", + }; } private function getLastEditorInfo($terminId) @@ -446,11 +445,20 @@ class Data { - public function changeTermin($id, $was, $value){ - $this->pdo->query("UPDATE termine SET $was = '" . $value . "' WHERE id = '" . $id . "'"); - //$this->updateCalendarEvent($id, $startzeit, $endzeit, $summary, $location, $beschreibung); + public function changeTermin($id, $was, $value): void { + $allowed = [ + 'startzeit', 'endzeit', 'location', 'locationtype', + 'gage', 'anwesend', 'beschreibung', 'status', + 'ansprechpartner', 'preisprostunde', 'realendzeit', + ]; - return; + if (!in_array($was, $allowed, true)) { + throw new InvalidArgumentException("Ungültige Spalte: " . $was); + } + + $sql = "UPDATE termine SET `" . $was . "` = :value WHERE id = :id"; + $stmt = $this->pdo->prepare($sql); + $stmt->execute([':value' => $value, ':id' => $id]); } private function icsEscape($text) { @@ -586,51 +594,53 @@ class Data { - public function setTerminStatus($id, $status){ - $this->pdo->query("UPDATE termine SET status = '" . $status . "' WHERE id = '" . $id . "'"); - return; + public function setTerminStatus($id, $status): void { + $this->changeTermin($id, 'status', $status); } - public function setTodoTitle($id, $title){ - $this->pdo->query("UPDATE todo SET title = '" . $title . "' WHERE id = '" . $id . "'"); - return; + public function setTodoTitle($id, $title): void { + $stmt = $this->pdo->prepare("UPDATE todo SET title = :title WHERE id = :id"); + $stmt->execute([':title' => $title, ':id' => $id]); } - public function setTodoDescription($id, $description){ - $this->pdo->query("UPDATE todo SET description = '" . $description . "' WHERE id = '" . $id . "'"); - return; + public function setTodoDescription($id, $description): void { + $stmt = $this->pdo->prepare("UPDATE todo SET description = :desc WHERE id = :id"); + $stmt->execute([':desc' => $description, ':id' => $id]); } - public function deleteTodoById($id){ - $this->pdo->query("DELETE FROM todo WHERE id = '" . $id . "'"); - return; + public function deleteTodoById($id): void { + $stmt = $this->pdo->prepare("DELETE FROM todo WHERE id = :id"); + $stmt->execute([':id' => $id]); } - public function createTodo($id, $title, $description){ - $this->pdo->query("INSERT INTO todo (creator, title, description) VALUES ('" . $id . "', '" . $title . "', '" . $description . "')"); - return; + public function createTodo($id, $title, $description): void { + $stmt = $this->pdo->prepare("INSERT INTO todo (creator, title, description) VALUES (:creator, :title, :desc)"); + $stmt->execute([':creator' => $id, ':title' => $title, ':desc' => $description]); } public function getTodoDataById($id, $column){ - $sql = "SELECT * FROM todo WHERE id = '" . $id . "'"; - foreach($this->pdo->query($sql) as $row) { - return $row[$column]; - } + $stmt = $this->pdo->prepare("SELECT * FROM todo WHERE id = :id"); + $stmt->execute([':id' => $id]); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + return $row[$column] ?? null; } - public function getAllReadyGigs(){ - $nRows = $this->pdo->query('select count(*) from termine WHERE status = 1')->fetchColumn(); - return $nRows; + public function getAllReadyGigs(): int { + $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM termine WHERE status = :status"); + $stmt->execute([':status' => 1]); + return (int)$stmt->fetchColumn(); } - public function getAllProcessingGigs(){ - $nRows = $this->pdo->query('select count(*) from termine WHERE status = 0')->fetchColumn(); - return $nRows; + public function getAllProcessingGigs(): int { + $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM termine WHERE status = :status"); + $stmt->execute([':status' => 0]); + return (int)$stmt->fetchColumn(); } - public function getAllCompletedGigs(){ - $nRows = $this->pdo->query('select count(*) from termine WHERE status = 2')->fetchColumn(); - return $nRows; + public function getAllCompletedGigs(): int { + $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM termine WHERE status = :status"); + $stmt->execute([':status' => 2]); + return (int)$stmt->fetchColumn(); } private function debugLog($msg) {