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 →

Interdire l'exécution de PHP dans les dossiers d'upload

Un webshell a besoin de deux choses : un dossier où il peut être écrit et un serveur qui l'exécute. Voici comment lui retirer la seconde, dans chaque dossier accessible en écriture, pas seulement dans uploads.

État 7 min de lectureDurcissement et configuration

En bref : pour interdire l'exécution de PHP dans les uploads, déterminez d'abord tous les dossiers dans lesquels PHP peut écrire, puis bloquez dans chacun d'eux l'exécution de scripts dans la configuration du serveur, pas par .htaccess. Dans Nginx, le blocage doit s'appliquer avant le bloc PHP général ; dans Apache, il a sa place dans le VirtualHost avec AllowOverride None. security.limit_extensions = .php dans le pool FPM et un test avec un fichier inoffensif terminent le travail.

Pourquoi les dossiers d'upload comptent justement maintenant

Après une faille critique comme PHP2Shell, les attaquants veulent rarement n'exécuter du code qu'une seule fois. Ils veulent revenir, même si le serveur est corrigé plus tard. La voie la plus simple est un webshell : un petit fichier PHP, déposé dans un dossier accessible en écriture et appelé ensuite via le navigateur.

Un correctif ne supprime pas un tel fichier. Qui était en ligne sans correctif à partir du 20 octobre 2026 devrait donc non seulement mettre à jour, mais aussi vérifier si de nouveaux fichiers PHP se trouvent quelque part, et empêcher à l'avenir leur exécution. La manière d'interpréter les trouvailles est décrite dans Fichiers PHP dans le dossier d'upload : bien interpréter les trouvailles.

Le blocage de l'exécution s'attaque à la seconde condition. Il n'empêche pas qu'un fichier soit déposé, mais que le serveur le traite comme un programme.

D'abord l'inventaire : où PHP peut-il écrire ?

La plupart des guides ne citent que le dossier d'upload. En pratique, une application PHP écrit à bien plus d'endroits. Chacun d'eux qui est accessible via le serveur web a besoin du blocage.

Type de dossier Contenu typique Pourquoi accessible en écriture
Uploads, médias images, PDF, pièces jointes utilisateurs et rédaction téléversent des fichiers
Cache pages générées, miniatures l'application accélère la diffusion
Temp, import, export fichiers CSV, états intermédiaires interfaces et échange de données
Sauvegardes dans la racine web .zip, .sql des extensions sauvegardent « sur place »
Journaux dans la racine web journaux d'erreurs et de débogage applications mal configurées

Une recherche avec les droits de l'utilisateur d'exécution montre quels dossiers sont concernés sur votre serveur. Elle ne modifie rien :

# Tous les dossiers sous /var/www dans lesquels l'utilisateur PHP peut écrire
# (adapter l'utilisateur : www-data, nginx, apache ou utilisateur de pool dédié)
sudo -u www-data find /var/www -type d -writable 2>/dev/null | sort
# Y a-t-il déjà des fichiers PHP dans ces dossiers ?
sudo -u www-data find /var/www -type d -writable -print0 2>/dev/null \
  | xargs -0 -I{} find {} -maxdepth 1 -type f -iname "*.ph*" 2>/dev/null

Si la première recherche renvoie toute la racine web, le code du programme appartient à l'utilisateur d'exécution. Vous devriez d'abord changer cela, comme le décrit le guide Droits sur les fichiers du serveur web. Sinon, il n'existe aucun dossier qui n'aurait pas à être bloqué.

Interdire l'exécution de PHP dans les uploads : Nginx

Avec Nginx, l'ordre décide. Selon la documentation de Nginx, les expressions régulières sont vérifiées dans l'ordre du fichier de configuration, et la première correspondance l'emporte. Si le bloc général location ~ \.php$ précède votre blocage, le fichier est exécuté. Une simple location par préfixe sans ^~ ne protège pas, pour la même raison.

Une expression régulière pour tous les dossiers bloqués, placée avant le bloc PHP, est sûre. Elle couvre aussi les extensions rarement utilisées :

server {
    # ... configuration de base ...

    # 1. Blocage des dossiers accessibles en écriture, DOIT précéder le bloc PHP
    location ~* ^/(uploads|media|cache|tmp|export)/.*\.(php\d?|phtml|phar|pht|phps)$ {
        deny all;
    }

    # 2. Bloc PHP général : ne transmettre que les fichiers existants
    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/seite1.sock;
    }
}

Adaptez les noms de dossiers à votre inventaire. Pour les applications à point d'entrée unique, la voie d'une liste d'autorisation est encore plus solide ; le schéma est présenté dans Configurer Nginx pour PHP en toute sécurité.

Apache et PHP-FPM : le blocage au bon endroit

Dans Apache, le blocage a sa place dans la configuration du serveur ou le VirtualHost. Un .htaccess dans le dossier d'upload est inadapté, car quiconque peut y écrire peut le modifier. Pour toute la racine web, AllowOverride None s'applique donc. Selon la documentation d'Apache, AllowOverride n'est autorisé que dans des blocs <Directory> sans expressions régulières ; définissez-le donc à la racine web et le blocage par <DirectoryMatch> en dessous :

<Directory /var/www/seite1/public>
    AllowOverride None
    Require all granted
</Directory>

<DirectoryMatch "^/var/www/seite1/public/(uploads|media|cache|tmp|export)/">
    <FilesMatch "\.(php\d?|phtml|phar|pht|phps)$">
        Require all denied
    </FilesMatch>
</DirectoryMatch>

Si mod_php tourne encore, ajoutez php_admin_flag engine off dans le même bloc. Avec PHP-FPM, une seconde barrière agit dans le pool : security.limit_extensions détermine quelles extensions FPM exécute. Selon le manuel PHP, la valeur par défaut est .php .phar ; la limitation à .php est recommandée.

; dans le pool, par ex. /etc/php/8.3/fpm/pool.d/seite1.conf
security.limit_extensions = .php

Tester avec un fichier inoffensif

Seul un test montre si le blocage agit. Placez brièvement dans chaque dossier bloqué un fichier qui se contente d'afficher un texte, appelez-le via le domaine, puis supprimez-le.

  1. Vérifier la configuration : nginx -t ou apachectl configtest, puis recharger.
  2. Créer le fichier de test, par exemple uploads/sperrtest.php avec le contenu <?php echo 'ausgefuehrt';.
  3. L'appeler avec curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/uploads/sperrtest.php. On attend 403.
  4. Si 200 apparaît à la place, avec le texte « ausgefuehrt », le blocage ne s'applique pas. Vérifier la configuration et l'ordre.
  5. Supprimer le fichier de test et répéter le test pour chaque dossier et chaque site.
Important

Si, lors de l'inventaire, vous trouvez déjà des fichiers PHP inconnus dans des dossiers accessibles en écriture, ne supprimez rien précipitamment. Sauvegardez d'abord l'état et les journaux, car ces fichiers sont des éléments de preuve. La marche à suivre ensuite est décrite dans Reconnaître et supprimer les webshells.

La manière de construire en toute sécurité les fonctions d'upload dans le code, avec contrôle de type et stockage en dehors de la racine web, est décrite dans le guide Mettre en œuvre les uploads de fichiers en PHP en toute sécurité.

Conclusion : écrire oui, exécuter non

Le blocage de l'exécution dans les dossiers accessibles en écriture est l'une des mesures isolées les plus efficaces contre les portes dérobées durables. Il coûte quelques lignes de configuration et ne casse rien dans les applications proprement construites. Trois points sont décisifs : un inventaire complet plutôt que le seul dossier d'upload évident, le bon ordre dans Nginx ou le bon niveau dans Apache, et un vrai test avec un fichier inoffensif.

Complété par des propriétaires distincts pour le code du programme, security.limit_extensions dans le pool et une recherche régulière de nouveaux fichiers PHP, on aboutit à un état où un fichier déposé est certes gênant, mais guère exploitable. Cela ne remplace ni la mise à jour ni la recherche de traces, mais retire aux attaquants l'un de leurs outils les plus importants.

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

  • Inventaire : nous déterminons tous les dossiers accessibles en écriture par site et vérifions s'ils contiennent des fichiers PHP.
  • Poser les blocages : nous inscrivons les blocages d'exécution dans Nginx, Apache et PHP-FPM, dans le bon ordre et sans dépendance à .htaccess.
  • Tester : nous vérifions chaque blocage avec un fichier inoffensif et documentons le résultat.
  • Nettoyer : en cas de trouvailles, nous assurons la sauvegarde des traces et la suppression de logiciels malveillants.

Questions fréquentes

Un .htaccess dans le dossier d'upload suffit-il pour interdire PHP ?

Pas de façon fiable. Qui peut écrire dans le dossier peut aussi modifier ou remplacer le .htaccess. Le blocage doit figurer dans la configuration du serveur ou le VirtualHost, et AllowOverride None devrait s'appliquer à la racine web.

Quels dossiers dois-je bloquer ?

Tous les dossiers dans lesquels l'utilisateur PHP peut écrire et qui sont accessibles via le serveur web. Outre les dossiers d'upload, ce sont souvent les répertoires de cache, temporaires, d'import, d'export et de sauvegarde. Déterminez-les par une recherche effectuée en tant qu'utilisateur d'exécution.

Le blocage casse-t-il mon site ?

En général non, car dans les dossiers d'upload et de cache des applications propres, il n'y a pas de scripts appelés directement. Mais certaines extensions y déposent tout de même des fichiers PHP. Testez donc les fonctions principales après le changement.

Le blocage protège-t-il contre PHP2Shell ?

Non. PHP2Shell est une faille de l'interpréteur PHP, qui n'est fermée que par la mise à jour et le redémarrage de tous les workers. Mais le blocage empêche qu'un fichier déposé soit ensuite appelé via le navigateur et utilisé comme porte dérobée durable.

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