Einfache Serververwaltung mit PHP und MySQL Sicherheit
Zur Navigation springen
Zur Suche springen
Sicherheitserweiterung für das Projekt "Serververwaltung"
Ziel
Dieses Dokument verbessert die Sicherheit des bestehenden Projekts „Serververwaltung“, indem es unsichere Praktiken durch sichere Alternativen ersetzt – konkret am bestehenden Quellcode und Setup.
Übersicht der Verbesserungen
- Kein Datenbankzugriff mit Root-Rechten
- Kein Klartextpasswort im Webverzeichnis
- Nutzung von Prepared Statements gegen SQL-Injection
- Keine Fehlermeldungen an Benutzer
- Sessions korrekt abgesichert
Sicherer Datenbankbenutzer
Statt root wird ein eingeschränkter Benutzer webapp verwendet:
CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'sicheres-passwort'; GRANT SELECT, INSERT, UPDATE, DELETE ON serververwaltung.* TO 'webapp'@'localhost'; FLUSH PRIVILEGES;
Zugangsdaten auslagern
Die Datei mit Zugangsdaten wird außerhalb des Webroots gespeichert: /etc/serververwaltung/db.conf.php
<?php return [ 'host' => '127.0.0.1', 'user' => 'webapp', 'pass' => 'sicheres-passwort', 'name' => 'serververwaltung' ];
Dateiberechtigungen setzen:
chmod 640 /etc/serververwaltung/db.conf.php chown root:www-data /etc/serververwaltung/db.conf.php
Überarbeitung der Datei db.php
<?php
$config = require('/etc/serververwaltung/db.conf.php');
$conn = new mysqli($config['host'], $config['user'], $config['pass'], $config['name']);
if ($conn->connect_error) {
error_log("DB-Verbindung fehlgeschlagen: " . $conn->connect_error);
die("Interner Fehler. Bitte später erneut versuchen.");
}
Absicherung der Datei login.php
Verwendung von Prepared Statements statt direktem SQL und sichere Passwort-Hashes.
<?php
session_start();
include 'db.php';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$benutzername = $_POST["benutzername"];
$passwort = $_POST["passwort"];
$stmt = $conn->prepare("SELECT passwort, rolle FROM benutzer WHERE benutzername = ?");
$stmt->bind_param("s", $benutzername);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
if (password_verify($passwort, $row['passwort'])) {
$_SESSION["benutzername"] = $benutzername;
$_SESSION["rolle"] = $row["rolle"];
header("Location: auswahl.html");
exit;
}
}
echo "Falsche Anmeldedaten.";
}
Passwort-Hash bei Benutzeranlage
Beim Erstellen neuer Benutzer:
insert into benutzer (benutzername, passwort, rolle)
values ('admin', 'REPLACE_DURCH_HASH', 'admin');
Beispiel für Passwort-Hash in PHP generieren:
php -r "echo password_hash('radler', PASSWORD_DEFAULT);"
Eintrag mit Prepared Statement (eintragen.php)
<?php
include 'db.php';
session_start();
if (!isset($_SESSION["benutzername"])) {
header("Location: login.html");
exit;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$stmt = $conn->prepare("INSERT INTO server (rechnername, ip_adresse, betriebssystem, festplattenspeicher, ram, hauptdienst)
VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param("sssdds",
$_POST["rechnername"],
$_POST["ip_adresse"],
$_POST["betriebssystem"],
$_POST["festplattenspeicher"],
$_POST["ram"],
$_POST["hauptdienst"]
);
if ($stmt->execute()) {
header("Location: liste.php");
exit;
} else {
error_log("Fehler beim Eintrag: " . $stmt->error);
echo "Interner Fehler beim Eintrag.";
}
}
Session-Absicherung
Session-Cookie absichern:
In PHP-Ini oder am Anfang des Scripts:
session_set_cookie_params([ 'lifetime' => 0, 'path' => '/', 'domain' => '', // ggf. setzen 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]); session_start();
HTTPS
Das Projekt läuft nur über HTTPS. HTTP wird per Apache umgeleitet:
Datei: /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
ServerName server.it113.int
Redirect permanent / https://server.it113.int/
</VirtualHost>
Aktivieren:
a2ensite default-ssl a2enmod rewrite a2enmod ssl systemctl reload apache2
Zusammenfassung
- Root-Nutzer ersetzt
- Passwörter aus Webverzeichnis entfernt
- Alle SQL-Zugriffe auf Prepared Statements umgestellt
- Passwörter gehasht
- Fehlerprotokollierung statt Benutzeranzeige
- Sessions und HTTPS korrekt konfiguriert