', '<=', '>=', 'LIKE']; function isValidEntry(string $name): bool { return (bool) preg_match('/^[a-zA-Z0-9_]+$/', $name); } function PermittedSchemas(array $deniedTables): array { static $cache = null; if ($cache !== null) { return $cache; } $alleSchemas = DatabaseShowAllSchemas(); // 1 Query statt N+1 $schema = []; foreach ($alleSchemas as $table => $columns) { if (!isValidEntry($table)) { continue; } if (in_array($table, $deniedTables, true)) { continue; } $schema[$table] = $columns; } $cache = $schema; return $schema; } $erlaubteSchema = PermittedSchemas($deniedTables); function isValidTable(string $table, array $schema): void { if (!isValidEntry($table) || !isset($schema[$table])) { throw new InvalidArgumentException("Tabelle nicht erlaubt: $table"); } } function isValidColumn(string $table, array $columns, array $schema): void { foreach ($columns as $col) { if (!isValidEntry($col) || !in_array($col, $schema[$table], true)) { throw new InvalidArgumentException("Spalte nicht erlaubt: $col"); } } } function buildWhere(array $conditions, string $table, array $schema, array $validOperations): array { $parts = []; $values = []; foreach ($conditions as $cond) { $col = $cond['column'] ?? ''; $op = $cond['operator'] ?? '='; $val = $cond['value'] ?? null; isValidColumn($table, [$col], $schema); if (!in_array($op, $validOperations, true)) { throw new InvalidArgumentException("Ungültiger Operator: $op"); } $parts[] = "`$col` $op ?"; $values[] = $val; } return [implode(' AND ', $parts), $values]; } // Request einlesen $daten = json_decode(file_get_contents('php://input'), true) ?? []; $action = $daten['action'] ?? ''; $table = $daten['table'] ?? ''; try { isValidTable($table, $erlaubteSchema); switch ($action) { case 'insert': { $columns = $daten['columns'] ?? []; $values = $daten['values'] ?? []; isValidColumn($table, $columns, $erlaubteSchema); if (count($columns) !== count($values)) { throw new InvalidArgumentException('Anzahl der Werte passt nicht zu den Spalten'); } $columnsSql = implode(', ', array_map(fn($c) => "`$c`", $columns)); $result = DatabaseInsert($table, $columnsSql, ...$values); echo json_encode(['success' => $result]); break; } case 'show': { $columns = $daten['columns'] ?? []; $conditions = $daten['conditions'] ?? []; if (empty($columns)) { $columns = $erlaubteSchema[$table]; } else { isValidColumn($table, $columns, $erlaubteSchema); } $columnsSql = implode(', ', array_map(fn($c) => "`$c`", $columns)); [$whereSql, $values] = buildWhere($conditions, $table, $erlaubteSchema, $validOperations); $result = DatabaseShow($table, $columnsSql, $whereSql, ...$values); echo json_encode(['success' => true, 'entries' => array_values($result ?? [])]); break; } case 'update': { $updates = $daten['updates'] ?? []; $conditions = $daten['conditions'] ?? []; if (empty($conditions)) { throw new InvalidArgumentException('WHERE-Bedingung ist bei UPDATE Pflicht'); } isValidColumn($table, array_keys($updates), $erlaubteSchema); $setParts = []; $setValues = []; foreach ($updates as $col => $val) { $setParts[] = "`$col` = ?"; $setValues[] = $val; } $setSql = implode(', ', $setParts); [$whereSql, $whereValues] = buildWhere($conditions, $table, $erlaubteSchema, $validOperations); $result = DatabaseUpdate($table, $setSql, $whereSql, ...array_merge($setValues, $whereValues)); echo json_encode(['success' => $result]); break; } case 'delete': { $conditions = $daten['conditions'] ?? []; if (empty($conditions)) { throw new InvalidArgumentException('WHERE-Bedingung ist bei DELETE Pflicht'); } [$whereSql, $values] = buildWhere($conditions, $table, $erlaubteSchema, $validOperations); $result = DatabaseDelete($table, $whereSql, ...$values); echo json_encode(['success' => $result]); break; } default: throw new InvalidArgumentException("Unbekannte Aktion: $action"); } } catch (InvalidArgumentException $e) { http_response_code(400); echo json_encode(['error' => $e->getMessage()]); } catch (Throwable $e) { http_response_code(500); error_log($e->getMessage()); echo json_encode(['error' => 'Serverfehler']); }