Situation actuelle : PHP2Shell. Deux failles PHP critiques (CVSS 9.2) permettent d'exécuter du code malveillant sans authentification. Correctifs disponibles depuis le 21 octobre 2026.Ce qu'il faut faire maintenant →

Prévenir la Local File Inclusion en PHP : LFI et RFI

Quand include ou require reprennent des chemins issus de la requête, des attaquants peuvent charger des fichiers étrangers. Comment construire en sécurité la sélection de pages et les modèles, et sécuriser en plus le serveur.

État 7 min de lectureGuides

En bref : la Local File Inclusion en PHP apparaît lorsque include, require ou des fonctions de fichiers utilisent un chemin que le visiteur peut influencer. La solution sûre est une liste d'autorisation fixe : le paramètre ne choisit que parmi des valeurs connues, le chemin lui-même ne vient jamais de la requête. Côté serveur, allow_url_include=Off, open_basedir et des droits de fichiers restrictifs complètent la protection.

Qu'est-ce que la Local File Inclusion en PHP ?

De nombreuses anciennes applications PHP chargent les pages selon un schéma simple : un paramètre dans l'adresse détermine quel fichier est inclus. Si ce paramètre est transmis sans vérification à include, un attaquant peut demander d'autres fichiers sur le serveur. Dans le cas le moins grave, il lit des fichiers de configuration contenant des identifiants. Dans le pire des cas, il amène PHP à exécuter des contenus qu'il a déposés auparavant ailleurs, par exemple dans un upload ou un fichier journal.

Pour la direction, l'important est que cette faille se trouve rarement dans le noyau du CMS, mais le plus souvent dans des développements sur mesure, d'anciennes extensions ou des pages complémentaires construites à la hâte. Elle passe inaperçue au quotidien, car le site fonctionne normalement.

Dans la Remote File Inclusion, PHP charge du code depuis une adresse étrangère. Cela suppose que allow_url_include soit activé. Dans les versions actuelles de PHP, ce réglage est désactivé par défaut, mais on le trouve encore sur d'anciens serveurs ou des serveurs mal configurés.

Schémas vulnérables typiques dans le code

Sont menacés les endroits où une valeur issue de la requête, des cookies ou de la base de données devient une partie d'un chemin de fichier. Exemples fréquents : les sélecteurs de langue qui chargent un fichier de langue d'après un paramètre, la sélection de pages via un paramètre dans l'adresse, le choix de modèles ou de thèmes et les scripts de téléchargement de documents. Un .php ajouté à la fin du chemin ne protège pas de façon fiable, car les attaquants peuvent se rabattre sur des fichiers PHP existants.

Vous obtenez une première vue d'ensemble avec une recherche des inclusions contenant des variables. Elle livre aussi des résultats inoffensifs, mais montre où il faut regarder de plus près :

grep -rnE --include='*.php' '(include|require)(_once)?\s*\(?\s*\$' /var/www/projekt \
  | grep -v '/vendor/'

Vérifiez pour chaque résultat d'où provient la variable et si un visiteur peut l'influencer.

Le schéma sûr : liste d'autorisation au lieu d'un chemin issu de la requête

La protection la plus fiable est que le visiteur ne choisisse qu'une clé et que l'application décide elle-même quel fichier y correspond. Le chemin n'est jamais assemblé à partir de saisies.

<?php
declare(strict_types=1);

$seiten = [
    'start'      => __DIR__ . '/../vorlagen/start.php',
    'leistungen' => __DIR__ . '/../vorlagen/leistungen.php',
    'kontakt'    => __DIR__ . '/../vorlagen/kontakt.php',
];

$wahl = is_string($_GET['seite'] ?? null) ? $_GET['seite'] : 'start';

if (!array_key_exists($wahl, $seiten)) {
    http_response_code(404);
    $wahl = 'start';
}

require $seiten[$wahl];

Ce schéma est court, facile à vérifier et ne laisse aucune marge. Dans les frameworks modernes, le routeur assume cette tâche ; là aussi, les contrôleurs et les modèles ne devraient jamais être déterminés par des paramètres libres.

Quand les noms de fichiers doivent être dynamiques : realpath et répertoire de base

Parfois, une liste fixe n'est pas praticable, par exemple pour des téléchargements depuis un dossier de documents. Vérifiez alors le chemin résolu par rapport à un répertoire de base fixe et n'autorisez que de simples noms de fichiers.

<?php
declare(strict_types=1);

const BASIS = '/var/www/daten/dokumente';

function sichererPfad(string $name): string
{
    if (!preg_match('/^[a-z0-9_-]{1,64}\.pdf$/', $name)) {
        throw new InvalidArgumentException('Ungültiger Dateiname.');
    }

    $basis = realpath(BASIS);
    $pfad  = realpath($basis . DIRECTORY_SEPARATOR . $name);

    if ($basis === false || $pfad === false
        || !str_starts_with($pfad, $basis . DIRECTORY_SEPARATOR)) {
        throw new RuntimeException('Datei nicht gefunden.');
    }

    return $pfad;
}

// Livrer au lieu d'inclure : readfile() n'exécute aucun code.
$datei = sichererPfad((string) ($_GET['datei'] ?? ''));
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($datei) . '"');
readfile($datei);

Deux points sont décisifs. L'expression régulière n'autorise ni séparateurs de répertoires ni caractères spéciaux. Et les fichiers qui doivent seulement être livrés sont lus avec readfile(), pas avec include, afin que le code qu'ils contiennent ne soit jamais exécuté. str_starts_with() est disponible à partir de PHP 8.0.

Sécurisation côté serveur : php.ini, open_basedir et droits

Un code sûr est la première ligne de défense. La configuration du serveur fait en sorte qu'une erreur négligée cause moins de dégâts.

; php.ini ou pool FPM (php_admin_value / php_admin_flag)
allow_url_include = Off
allow_url_fopen   = Off   ; seulement si l'application ne charge aucune URL externe
open_basedir      = /var/www/kunde-a/:/tmp/kunde-a/
display_errors    = Off
log_errors        = On

Certaines applications ont besoin de allow_url_fopen pour les mises à jour ou les interfaces. Testez d'abord la désactivation sur un environnement de test. open_basedir limite PHP aux répertoires propres au site, ce qui est particulièrement important sur les serveurs hébergeant plusieurs clients. Les détails figurent dans les guides open_basedir et isolation par site web et Configurer php.ini de façon sécurisée.

En complément, les répertoires d'upload et de cache ne devraient pas être exécutables et les fichiers journaux ne devraient pas se trouver dans la racine web. Un attaquant manque alors des endroits où il pourrait déposer son propre contenu en vue d'une inclusion.

À quoi reconnaître des tentatives d'exploitation dans les journaux

Les tentatives d'exploiter une inclusion de fichier laissent généralement des traces dans le journal d'accès. Sont suspects les paramètres qui contiennent des changements de répertoire, des chemins système absolus, des wrappers de flux ou des adresses étrangères complètes, notamment pour des paramètres comme page, file, template ou lang. Un résultat isolé est le plus souvent un balayage automatisé. L'important est de savoir si une telle requête a reçu une réponse avec le code de statut 200 et une taille de réponse inhabituelle.

La démarche systématique est décrite dans Analyser les journaux du serveur web après une attaque. Si vous trouvez des indices d'accès réussis, partez du principe que des fichiers de configuration ont été lus et renouvelez les identifiants qu'ils contiennent.

Cela concerne surtout les mots de passe de base de données, les clés des services de paiement et d'expédition, les accès SMTP et les clés secrètes du CMS. Vérifiez en outre si de nouveaux fichiers sont apparus depuis le premier accès suspect. Qui a pu lire des fichiers a peut-être aussi tenté d'en déposer. Dans ce cas, il ne s'agit plus seulement d'une faille dans le code, mais d'un incident de sécurité qui devrait être traité de façon structurée.

Sécuriser durablement les corrections

Après une correction, il vaut la peine de sécuriser la fonction de protection par des tests automatisés. Un test simple transmet à la sélection de pages des valeurs inconnues, des changements de répertoire et des entrées vides, et attend dans tous les cas la page par défaut ou une erreur 404. De tels tests empêchent qu'une modification ultérieure rouvre la faille sans qu'on s'en aperçoive.

Pour la direction et les responsables de projet, une question à l'agence est utile : y a-t-il dans l'application des endroits où des fichiers sont chargés d'après des paramètres, et comment sont-ils sécurisés ? Une réponse concrète avec les endroits concernés et les tests est un bon signe.

Comment PHP SOS aide-t-il concrètement ?

  • Nous recherchons dans votre code, de façon ciblée, include, require et les fonctions de fichiers utilisant des saisies de la requête, et évaluons chaque constat.
  • Nous définissons allow_url_include, open_basedir et les droits adaptés par site, et vérifions que l'application continue de fonctionner ensuite.
  • Nous analysons les journaux à la recherche de tentatives d'exploitation et clarifions si des identifiants doivent être renouvelés.
  • Pour un contrôle indépendant, nous proposons un audit de sécurité avec test d'intrusion pour les applications PHP.

Questions fréquentes

Quelle est la différence entre LFI et RFI ?

Dans la Local File Inclusion, l'application charge un fichier qui se trouve déjà sur le serveur mais ne devrait pas être chargé. Dans la Remote File Inclusion, du code est chargé depuis une adresse étrangère. La RFI suppose un réglage PHP peu sûr, la LFI non.

Suffit-il de supprimer ../ du paramètre ?

Non. De tels filtres se contournent souvent par encodage ou variantes et négligent les chemins absolus. Seules une association fixe de valeurs autorisées à des fichiers ou une vérification du chemin résolu par rapport à un répertoire de base sont sûres.

open_basedir protège-t-il entièrement contre l'inclusion de fichiers ?

Non, il limite seulement les répertoires auxquels PHP peut accéder. À l'intérieur de ces limites, une faille reste exploitable. open_basedir est une couche de protection supplémentaire et ne remplace pas un code sûr.

Les CMS comme WordPress sont-ils concernés par la LFI ?

Le noyau des CMS courants est considéré comme bien vérifié sur ce point. Les failles apparaissent plutôt dans les extensions, les thèmes et les développements sur mesure. Les mises à jour des extensions et un coup d'œil à leurs avis de sécurité sont donc importants.

Sources

Contact immédiat

Chaque heure compte. Écrivez-nous maintenant.

Décrivez brièvement votre système, votre version de PHP et ce que vous avez observé. Nous vous répondons, faisons le point et travaillons à distance jusqu'à la clôture et la documentation de l'incident.

Aide immédiate