Web-Sicherheit

Dateieinbindung (LFI / RFI)

Definition

Dateieinbindung (File Inclusion) ist eine PHP-Schwachstelle, bei der ein Angreifer den an include oder require übergebenen Pfad kontrolliert. Bei LFI (Local File Inclusion) lädt er eine Datei, die schon auf dem Server liegt, bei RFI (Remote File Inclusion) eine anderswo gehostete Datei. Die Folge: geleakte Geheimnisse oder Codeausführung.

Dateieinbindung (LFI / RFI), Web-Sicherheit

In PHP laden die Anweisungen include und require (und ihre Varianten mit _once) eine Datei und führen den darin enthaltenen Code aus. Sie werden überall eingesetzt, zum Beispiel um ein Template des Themes zu laden. Gefährlich wird es, wenn der Dateipfad von Daten abhängt, die der Besucher sendet, ohne dass sie ausreichend geprüft werden. Der Katalog von MITRE führt diese Schwäche als CWE-98, mit zwei gängigen Bezeichnungen: RFI für die entfernte, LFI für die lokale Einbindung.

So läuft der Angriff ab

Code wie dieser lässt den Besucher auswählen, welche Datei geladen wird:

// Bitte nicht so
include( __DIR__ . '/templates/' . $_GET['view'] . '.php' );
  • LFI (Local File Inclusion): Mit Sequenzen wie ../ klettert der Angreifer im Verzeichnisbaum nach oben und lässt eine Datei laden, die bereits auf dem Server liegt. Im besten Fall liest er eine Datei, die er nicht sehen dürfte; gelingt es ihm, eine Datei einzubinden, deren Inhalt er kontrolliert (ein Log, eine hochgeladene Datei), erreicht er eine Remote Code Execution.
  • RFI (Remote File Inclusion): Der Angreifer liefert eine URL, die auf seinen eigenen Server zeigt, und PHP bindet seinen Code direkt ein. Das ist die direkteste Form, sie setzt aber eine Einstellung voraus, die selten aktiviert ist.
Vergleich in drei Spalten: LFI (Einbindung einer Datei vom Server, Lesen oder Ausführen von wp-config.php über ../-Pfade, Wrapper php://filter und phar://, klappt mit der Standardkonfiguration), RFI (Einbindung einer http- oder ftp-URL mit dem Code des Angreifers, erfordert aktiviertes allow_url_include, eine standardmäßig deaktivierte und seit PHP 7.4 veraltete Einstellung) und Abwehr (feste Liste erlaubter Dateien, nie ein Pfad aus der Anfrage, open_basedir und allow_url_include aus, Updates)
RFI hängt von einer standardmäßig deaktivierten Einstellung ab; LFI dagegen funktioniert mit einer Standardkonfiguration.

Die Rolle der PHP-Konfiguration

Die PHP-Dokumentation ist bei zwei Direktiven eindeutig:

  • allow_url_include erlaubt URLs in include und require. Der Standardwert ist 0, die Einstellung lässt sich nur in der Systemkonfiguration (php.ini) ändern und ist seit PHP 7.4.0 veraltet. Außerdem muss allow_url_fopen aktiviert sein.
  • allow_url_fopen erlaubt PHP, URLs wie Dateien zu öffnen; die Option ist standardmäßig aktiv, weil viele Skripte sie brauchen.

RFI abzuschalten löst nicht alles: PHP-Wrapper wie php://filter können manche LFI-Lücken auf einer Standardkonfiguration in Codeausführung verwandeln, und phar:// diente lange dazu, eine unsichere Deserialisierung auszulösen. Unser Beitrag zu den Wrappern php://filter und phar erklärt diese Techniken im Detail.

Video: „Web Hacker Basics 04 (Local and Remote File Inclusion)“ (Netsec Explained, auf Englisch)

So schützt du dich

Die beste Abwehr, von MITRE empfohlen, besteht darin, nie einen Pfad aus empfangenen Daten zusammenzusetzen, sondern feste Werte bekannten Dateien zuzuordnen:

$views = array( 'list' => 'list.php', 'grid' => 'grid.php' );
$view  = isset( $views[ $_GET['view'] ?? '' ] ) ? $views[ $_GET['view'] ] : 'list.php';
include __DIR__ . '/templates/' . $view;
  • Leg eingebundene Dateien nach Möglichkeit außerhalb des Web-Roots ab.
  • Begrenze mit open_basedir, was PHP lesen darf: Ein umgeleitetes include kann die erlaubten Verzeichnisse dann nicht verlassen. PHP auf deinem Hosting härten erklärt diese Einstellung und ihre Auswirkungen.
  • Eine Web Application Firewall blockiert typische Muster (../, php://), allerdings nur als zusätzliche Schicht.

Für WordPress

Der WordPress-Core setzt seine includes nicht aus Besucherparametern zusammen: Das Risiko geht von Plugins und Themes aus, die ein Template, eine Sprachdatei oder ein Modul anhand eines URL- oder AJAX-Parameters laden. Das liebste LFI-Ziel ist wp-config.php mit den Zugangsdaten zur Datenbank und den Sicherheitsschlüsseln; eine im Web-Root vergessene sensible Datei, etwa eine .env-Datei oder ein Backup, ist ebenfalls leichte Beute, wie unser Beitrag über offen zugängliche sensible Dateien zeigt. Prüfe schließlich, dass dein Hoster allow_url_include deaktiviert lässt.

Quellen

  1. MITRE CWE-98: PHP Remote File Inclusion (externer Link, öffnet in neuem Tab)
  2. PHP Manual: Filesystem and Streams Configuration Options (externer Link, öffnet in neuem Tab)
  3. PHP Manual: Backward Incompatible Changes in PHP 8.0 (Phar) (externer Link, öffnet in neuem Tab)

Alle Definitionen

WordPress-Sicherheit ohne Lärm

Eine E-Mail, wenn es wichtig ist: neu beobachtete Angriffe, Updates des Plugins und praktische Anleitungen. Kein Spam, Abmeldung mit einem Klick.

Starte kostenlos und wechsle zu Pro, wenn du so weit bist

Die kostenlose Version versteckt WordPress bereits und verschiebt die Anmeldeseite. Pro ergänzt Aliasse, Zwei-Faktor-Authentifizierung und Überwachung.