flawopen.com/Dateieinbindung/PHP include()
Ist PHP include() mit Benutzereingaben sicher?
Nein. include() parst die ausgewählte Datei als PHP; die Auswirkung hängt jedoch von der erreichbaren Datei und ihrem Inhalt ab. Ein Fehler kann Quelltext über einen Wrapper offenlegen, eine unerwartete lokale Datei einbinden oder nur dann vom Angreifer kontrollierten PHP-Code ausführen, wenn dieser PHP-markierten Inhalt beeinflussen kann und die Anwendung ihn einbindet. Eine entfernte URL-Einbindung hängt zusätzlich von der PHP-Konfiguration ab. Ordne Benutzereingaben festen Schlüsseln einer Allowlist zu; setze den include-Pfad nie aus Request-Daten zusammen.
<?php // User-controlled path: unintended local file include $_GET['page'] . '.php'; // Example selector: ../../private/sample // Impact depends on the resolved file and // whether it contains PHP code to interpret. // Remote URL inclusion requires the relevant // URL wrapper and allow_url_include setting. // Wrappers can change which resource is read; // php://filter is a read filter, not a path // containment check.
<?php // Allowlist: input selects a KEY, // never a path or wrapper. $pages = [ 'home' => __DIR__ . '/pages/home.php', 'about' => __DIR__ . '/pages/about.php', 'contact' => __DIR__ . '/pages/contact.php', ]; $key = $_GET['page'] ?? 'home'; if (!is_string($key) || !array_key_exists($key, $pages)) { http_response_code(404); exit; } include $pages[$key];
Warum lokale Einbindung nicht automatisch Codeausführung bedeutet
Lokale Einbindung führt nicht automatisch Code aus. PHP parst die eingebundene Datei: Anweisungen in gültigen PHP-Tags laufen im Kontext der einbindenden Datei; andere Bytes können als Ausgabe erscheinen. Codeausführung setzt eine erreichbare Datei mit angreiferkontrolliertem PHP oder ein anderes ausnutzbares Verhalten voraus. Eine Upload- oder Log-Schreibschwachstelle kann Teil einer Angriffskette sein, wenn sie kontrollierten PHP-Inhalt in eine später eingebundene Datei schreibt.
php://filter wendet beim Öffnen eines Streams einen Filter an. In einem verwundbaren Lese- oder Einbindungsablauf kann ein geeigneter Filter Quelltext offenlegen, ohne ihn auszuführen; Zugriff hängt von Wrapper, Berechtigungen und Konfiguration ab.
Warum Pfadbereinigung nicht genügt
../ zu entfernen, eine feste Erweiterung anzuhängen oder ein Basisverzeichnis voranzustellen beweist nicht, dass die endgültige Ressource freigegeben ist. Kodierungen, absolute Pfade, Plattformregeln und Wrapper können die Interpretation ändern. Entferne die Kontrolle über den Ressourcennamen: Erlaube nur feste, anwendungseigene Schlüssel.
Falls ein Pfad aufgelöst werden muss, kanonisiere ihn mit realpath() und prüfe die Verzeichnisgrenze wie im Path-Traversal-Leitfaden. Beschränke das Ergebnis auf freigegebene Dateien und berücksichtige Symlinks sowie Check/use-Races. Eine Allowlist fester Ziele ist sicherer.
Häufige Fragen
Die Option deaktiviert URL-Wrapper für include/require. PHP dokumentiert sie standardmäßig als deaktiviert und seit PHP 7.4 als veraltet. Sie reduziert RFI-Risiken, verhindert aber weder lokalen Path Traversal noch unsichere lokale Includes. Lass sie deaktiviert und entferne die Benutzerkontrolle über das Ziel.
PHP 5.3.4 behob die Nullbyte-Terminierung bei der Pfadverarbeitung. Verlass dich nicht auf das Ende dieses alten Tricks: nicht vertrauenswürdige include-Ziele bleiben unsicher.
require und _once-Varianten binden das Ziel ebenfalls ein und parsen es; Fehler- und Wiederholungsverhalten unterscheiden sich, machen ein nicht vertrauenswürdiges Ziel aber nicht sicher. readfile() und file_get_contents() geben Daten zurück, ohne sie als PHP zu parsen; ein nicht vertrauenswürdiger Pfad kann Traversal oder Offenlegung bewirken, jedoch keine include-Codeausführung.