LFI: Teil 4 – Schutzmaßnahmen gegen LFI und Best Practices

Rückblick: Das Problem

Wir haben gesehen, dass LFI entsteht, wenn Anwendungen unkontrolliert Dateien anhand von Benutzereingaben laden.

  • Beispiel: include($_GET["page"]);
  • Angreifer: ?page=../../etc/passwd → Systemdateien werden sichtbar.
  • In Kombination (Log Poisoning, File Upload) → Remote Code Execution (RCE).

Die gute Nachricht: Mit den richtigen Maßnahmen lässt sich LFI zuverlässig verhindern.


1. Niemals direkte Includes aus Benutzereingaben

Das ist der Kernfehler:

$page = $_GET["page"];
include($page);

Angreifer haben hier freie Hand.

Besser: Whitelisting

$allowed_pages = [
  "home" => "home.php",
  "about" => "about.php",
  "contact" => "contact.php"
];

$page = $_GET["page"] ?? "home";

if (array_key_exists($page, $allowed_pages)) {
    include($allowed_pages[$page]);
} else {
    include("404.php");
}
  • Nur explizit erlaubte Dateien werden geladen.
  • Keine Chance für ../ oder fremde Pfade.

2. Mapping statt Dateinamen

Noch besser: Arbeite gar nicht mit Dateinamen, sondern mit internen Slugs oder IDs.

switch ($_GET["page"]) {
    case "home":
        showHome();
        break;
    case "about":
        showAbout();
        break;
    default:
        show404();
}

So haben Angreifer keinen Einfluss mehr auf Dateipfade.


3. Pfade validieren

Wenn man wirklich Dateien dynamisch laden muss, dann nur mit Validierung:

realpath() nutzen

$base = "/var/www/html/templates/";
$file = realpath($base . $_GET["file"]);

if ($file && strpos($file, $base) === 0) {
    include($file);
} else {
    include("404.php");
}
  • realpath() löst ../ auf.
  • strpos($file, $base) === 0 prüft, ob die Datei noch im erlaubten Verzeichnis liegt.

Damit wird Directory Traversal blockiert.


4. Keine unnötigen Fehlermeldungen

Fehlermeldungen verraten Angreifern, dass ein LFI-Versuch gestartet wurde.

Statt:

Warning: include(../../etc/passwd): failed to open stream...

→ Immer Fehlerbehandlung aktivieren:

ini_set("display_errors", 0);
error_log("include error: " . $_GET["file"]);

So sehen nur Admins die Details, Angreifer nicht.


5. Webserver-Härtung

Selbst wenn es in der Anwendung Fehler gibt, kannst du mit Server-Konfiguration das Risiko reduzieren.

Dateirechte minimal halten

  • Der Webserver (z. B. www-data) sollte nur Zugriff auf das Webroot haben.
  • Keine Lese-Rechte für /etc/, /var/log/, Home-Verzeichnisse.

Open_basedir in PHP

open_basedir=/var/www/html/

→ PHP darf nur in diesem Verzeichnis Dateien öffnen.

Disable gefährliche Funktionen

disable_functions = system, exec, shell_exec, passthru, popen, proc_open

So verhinderst du, dass eine LFI direkt in RCE eskaliert.


6. Monitoring & Detection

Verdächtige Requests erkennen

  • Parameter mit ../
  • URL-encoded Traversal (%2e%2e%2f)
  • PHP-Wrapper (php://filter)

Ein WAF oder Intrusion Detection System (IDS) kann diese Muster blocken oder melden.

Logs vergleichen

  • Auffällige 404-Fehler mit ungewöhnlichen Pfaden.
  • Viele aufeinanderfolgende Requests mit file=-Parametern.

7. Frameworks & moderne Patterns nutzen

Viele moderne Frameworks (Laravel, Django, Spring Boot) sind von Haus aus sicherer, weil sie:

  • Templates nicht direkt über Include-Pfade laden, sondern über ein Rendering-System.
  • Keine Dateinamen aus GET/POST übernehmen.
  • Strikte Routing-Mechanismen haben.

Wer mit modernen Frameworks arbeitet, reduziert das Risiko enorm.


8. Tests in der Entwicklungsphase

Unit-Tests

Schreibe Tests, die prüfen, ob unautorisierte Pfade blockiert werden:

$response = request("/?file=../../etc/passwd");
assert($response->status == 404);

Penetrationstests

Setze Tools wie Burp Suite oder OWASP ZAP ein, um gezielt auf LFI zu prüfen.


9. Typische Anti-Patterns vermeiden

  • Blacklisting: Nur ../ blocken reicht nicht → Angreifer nutzen %2e%2e%2f.
  • Anhängen von .php: Null Byte Injection oder Encodings können das umgehen.
  • Vertrauen auf Client-Side Controls: Dropdowns oder versteckte Felder im HTML sind keine Sicherheit – Angreifer ändern Parameter im Request.

10. Defense in Depth

LFI-Prävention funktioniert am besten mit mehreren Schichten:

  1. Input-Validierung (Whitelist).
  2. Server-Härtung (Rechte, open_basedir).
  3. Fehlerbehandlung (keine Infos nach außen).
  4. Monitoring (verdächtige Requests erkennen).
  5. Frameworks (sichere Routing-Systeme).

Analogie: Die Bibliothek mit Sicherheitsstufen

Erinnerst du dich an die Bibliotheks-Analogie?

  • Früher konnte jeder jedes Buch verlangen.
  • Jetzt gibt es:
    • Whitelist: Nur Bücher aus der offiziellen Liste.
    • realpath(): Bibliothekar prüft, ob das Buch wirklich aus dem erlaubten Regal kommt.
    • Serverrechte: Manche Räume sind für den Bibliothekar verschlossen.
    • Monitoring: Kameras melden verdächtige Besucher.

So bleibt die Bibliothek sicher.


Was du bis hier mitnehmen solltest

  • Nie direkte Includes aus Benutzereingaben.
  • Immer Whitelisting oder Mapping nutzen.
  • realpath() + Basisverzeichnis prüfen.
  • Serverrechte minimal halten (open_basedir, Dateirechte).
  • Moderne Frameworks statt eigener Include-Logik.
  • Monitoring & Tests ergänzen den Schutz.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert