Level 3 – Einfache Serververwaltung (Minimal)

Aus Xinux Wiki
Version vom 24. März 2026, 20:18 Uhr von Thomas.will (Diskussion | Beiträge) (→‎Anpassung: index.php (XSS Schutz))
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Level 3 – Absicherung der Anwendung (Security Hardening)

Voraussetzung

  • Level 2 muss vollständig umgesetzt und funktionsfähig sein
  • Benutzerverwaltung und Login existieren
  • Anwendung ist erreichbar unter:
   http://SERVER-IP/server

Ziel

  • Absicherung gegen SQL Injection
  • Sichere Speicherung von Passwörtern
  • Einführung von Rollen (admin / user)
  • Schutz vor Cross-Site-Scripting (XSS)

Erweiterung der Datenbank

  • Anmeldung an MariaDB
   mysql -u root
  • Datenbank auswählen
   use serververwaltung;
  • Tabelle erweitern (Rollen hinzufügen)
   alter table benutzer add rolle varchar(20);
  • Rollen setzen
   update benutzer set rolle='admin' where benutzername='admin';
   update benutzer set rolle='user' where benutzername='user';

Passwort-Hashing

  • Passwörter dürfen nicht im Klartext gespeichert werden
  • Stattdessen wird ein Hash verwendet
  • Beispiel (PHP):
<?php
echo password_hash("admin", PASSWORD_DEFAULT);
?>
  • Den erzeugten Hash in die Datenbank eintragen
   update benutzer set passwort='HASH_HIER_EINFUEGEN' where benutzername='admin';
   update benutzer set passwort='HASH_HIER_EINFUEGEN' where benutzername='user';

Datei: login.php (sicher)

  • Verwendung von Prepared Statements
  • Überprüfung des Passworts mit password_verify()
<?php
include 'db.php';
session_start();

$benutzername = $_POST['benutzername'];
$passwort = $_POST['passwort'];

$stmt = $conn->prepare("SELECT * 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['user'] = $benutzername;
        $_SESSION['rolle'] = $row['rolle'];
        header("Location: index.php");
        exit;
    }
}

echo "Login fehlgeschlagen";
?>

Datei: add.php (sicher)

  • Schutz durch Session
  • Verwendung von Prepared Statements
<?php
include 'db.php';
session_start();

if (!isset($_SESSION['user'])) {
    die("Nicht eingeloggt");
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $rechnername = $_POST["rechnername"];
    $ip_adresse = $_POST["ip_adresse"];
    $betriebssystem = $_POST["betriebssystem"];
    $festplattenspeicher = $_POST["festplattenspeicher"];
    $ram = $_POST["ram"];
    $hauptdienst = $_POST["hauptdienst"];

    $stmt = $conn->prepare("INSERT INTO server (rechnername, ip_adresse, betriebssystem, festplattenspeicher, ram, hauptdienst)
    VALUES (?, ?, ?, ?, ?, ?)");

    $stmt->bind_param("sssiss",
        $rechnername,
        $ip_adresse,
        $betriebssystem,
        $festplattenspeicher,
        $ram,
        $hauptdienst
    );

    if ($stmt->execute()) {
        header("Location: index.php");
        exit;
    } else {
        echo "Fehler";
    }
}
?>

Datei: delete.php (sicher)

  • Nur Admin darf löschen
  • Verwendung von Prepared Statements
<?php
include 'db.php';
session_start();

if (!isset($_SESSION['user'])) {
    die("Nicht eingeloggt");
}

if ($_SESSION['rolle'] !== 'admin') {
    die("Keine Berechtigung");
}

$id = $_GET['id'];

$stmt = $conn->prepare("DELETE FROM server WHERE id = ?");
$stmt->bind_param("i", $id);

if ($stmt->execute()) {
    echo "Server gelöscht";
} else {
    echo "Fehler";
}
?>

Anpassung: index.php (XSS Schutz)

  • Ausgabe der Daten absichern
<?php
session_start();
include 'db.php';
$result = $conn->query("SELECT * FROM server");
?>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Serververwaltung</title>
</head>
<body>

<?php
if (isset($_SESSION['user'])) {
    echo "Eingeloggt als: " . htmlspecialchars($_SESSION['user']) . "<br>";
} else {
    echo "<a href='login.html'>Login</a><br>";
}
?>

<h2>Neuen Server eintragen</h2>
<form method="post" action="add.php">
    Rechnername: <input type="text" name="rechnername" required><br>
    IP-Adresse: <input type="text" name="ip_adresse" required><br>
    Betriebssystem: <input type="text" name="betriebssystem" required><br>
    Festplatte (GB): <input type="number" name="festplattenspeicher" required><br>
    RAM (GB): <input type="number" name="ram" required><br>
    Hauptdienst: <input type="text" name="hauptdienst" required><br>
    <input type="submit" value="Speichern">
</form>

<h2>Serverliste</h2>

<?php
if ($result->num_rows > 0) {
    echo "<table border='1'>";
    echo "<tr><th>ID</th><th>Name</th><th>IP</th><th>OS</th><th>Disk</th><th>RAM</th><th>Dienst</th><th>Aktion</th></tr>";

    while ($row = $result->fetch_assoc()) {
        echo "<tr>";
        echo "<td>".$row["id"]."</td>";
        echo "<td>".htmlspecialchars($row["rechnername"])."</td>";
        echo "<td>".htmlspecialchars($row["ip_adresse"])."</td>";
        echo "<td>".htmlspecialchars($row["betriebssystem"])."</td>";
        echo "<td>".$row["festplattenspeicher"]."</td>";
        echo "<td>".$row["ram"]."</td>";
        echo "<td>".htmlspecialchars($row["hauptdienst"])."</td>";
        echo "<td><a href='delete.php?id=".$row["id"]."'>löschen</a></td>";
        echo "</tr>";
    }

    echo "</table>";
} else {
    echo "Keine Server vorhanden.";
}
?>

</body>
</html>

Test

  • Login mit admin/admin
  • Login mit user/user
  • SQL Injection testen
   ' OR 1=1 --
  • Ergebnis:
    • Login funktioniert NICHT mehr
  • Löschen testen
    • admin → funktioniert
    • user → wird verweigert

Ergebnis

  • Teilnehmer verstehen:
    • Warum SQL Injection gefährlich ist
    • Wie Prepared Statements schützen
    • Warum Passwort-Hashing notwendig ist
    • Wie Rollen Zugriff steuern
    • Warum Ausgaben gefiltert werden müssen