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 →

Bien protéger les identifiants et les fichiers .env

Comment protéger mots de passe de base de données, clés d'API et autres secrets dans les projets PHP : fichiers .env hors du webroot, blocage dans le serveur web, droits étroits et remplacement ordonné après un incident.

État 7 min de lectureDéveloppement sécurisé

En bref : vous protégez un fichier .env en veillant à ce qu'il ne se trouve même pas dans le répertoire accessible au public : le webroot pointe vers un sous-dossier comme public/, la configuration se trouve un niveau au-dessus. En outre, le serveur web bloque tous les fichiers commençant par un point, le fichier n'est lisible que par son propriétaire et le processus PHP, et il n'a jamais sa place dans le dépôt Git. Après une intrusion, tous les identifiants qu'il contient sont considérés comme connus et remplacés.

Le fichier qui contient les clés de la maison

Les projets PHP modernes déposent volontiers leurs secrets dans un fichier nommé .env : mot de passe de base de données, accès au serveur de messagerie, clés d'API des services de paiement et d'expédition, clé avec laquelle l'application signe les cookies. Des frameworks comme Laravel et Symfony utilisent ce modèle, et de nombreux développements internes l'ont repris.

L'idée est bonne : configuration et code sont séparés, et chaque environnement reçoit ses propres valeurs. Cela devient dangereux lorsque le fichier atterrit dans le mauvais répertoire. S'il se trouve dans le webroot et que le serveur web ne le bloque pas, un seul appel dans le navigateur suffit pour lire tous les accès d'un coup.

S'y ajoutent des variantes avec d'autres noms : .env.local, .env.production, config.local.php ou des fichiers contenant des identifiants de services de stockage. Ce qui est décrit ici pour .env vaut pour tous les fichiers où figurent des secrets.

Ces fichiers sont recherchés en permanence par des scanners automatisés. Ce n'est pas la spécialité de quelques attaquants, mais le bruit de fond d'Internet, comme les scans massifs à la recherche de versions de PHP non corrigées.

Où le fichier .env devrait se trouver

La mesure la plus efficace est structurelle : le serveur web ne doit diffuser que le dossier qui doit réellement être public. Dans Laravel et Symfony, c'est le dossier public/. Tout le reste, c'est-à-dire code, configuration, journaux et .env, se trouve au-dessus et n'est tout simplement pas adressable via HTTP.

/srv/www/shop/
├── .env              ← inaccessible
├── config/
├── src/
├── vendor/
└── public/           ← seul webroot
    ├── index.php
    └── assets/

En pratique, le webroot pointe pourtant souvent vers le répertoire du projet lui-même, par exemple parce qu'un panneau d'hébergement l'impose ou parce qu'un chemin n'a pas été adapté lors d'un déménagement. Vérifiez donc dans la configuration du serveur web ou dans le panneau vers quoi pointent root ou DocumentRoot.

Protéger le fichier .env : le blocage dans le serveur web comme seconde ligne

Si le webroot ne peut pas être modifié, ou si vous souhaitez une protection supplémentaire, bloquez les fichiers cachés dans le serveur web. Le dossier .well-known doit rester accessible, car il sert notamment à l'émission des certificats.

# Bloquer tous les fichiers et dossiers commençant par un point, sauf .well-known
location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}
# Bloquer les fichiers commençant par un point
<FilesMatch "^\.">
    Require all denied
</FilesMatch>

Une réponse 404 plutôt que 403 ne révèle pas que le fichier existe. Vous vérifiez depuis l'extérieur que le blocage fonctionne :

# Attendu : 403 ou 404, jamais 200
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env.example
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env.bak

Les deux dernières lignes ne sont pas un hasard : des copies comme .env.bak ou .env.old naissent lors des travaux de maintenance et sont souvent oubliées. Vous en saurez plus sur ces vestiges dans Fichiers de sauvegarde dans le webroot.

Droits, Git et gestion des copies

Même en dehors du webroot, le principe des droits minimaux s'applique. Une répartition éprouvée :

  1. Le propriétaire est l'utilisateur de déploiement, pas le processus PHP.
  2. Le groupe est celui du pool PHP-FPM, qui a seulement le droit de lecture ; droits 640.
  3. Aucun accès en écriture pour le processus PHP. Une application n'a pas besoin de pouvoir modifier ses propres identifiants.
  4. Aucune valeur réelle dans le dépôt : seul .env.example avec des valeurs d'exemple est versionné, le vrai fichier figure dans .gitignore.
  5. Valeurs distinctes par environnement : développement, préproduction et production utilisent des accès différents, afin qu'une fuite dans un environnement de test n'ouvre pas la production.
chown deploy:shop-php /srv/www/shop/.env
chmod 640 /srv/www/shop/.env
# Vérifier si le fichier a jamais été versionné
git log --all --oneline -- .env

Faites aussi attention aux pages d'erreur. En mode debug, les frameworks affichent parfois des variables d'environnement et des valeurs de configuration ; sur un système de production, ce mode doit être désactivé. Vérifiez-le après chaque déploiement, car une valeur erronée dans le .env lui-même peut le réactiver.

Si la dernière commande donne des résultats, les identifiants figurent dans l'historique Git et sont considérés comme exposés, même si le fichier n'existe plus aujourd'hui. Pourquoi c'est particulièrement délicat lorsque le dossier .git se trouve sur le serveur est décrit dans Dossier .git public : une fuite de données sous-estimée. Les principes sur les droits sont expliqués dans le guide Droits d'accès aux fichiers sur le serveur web.

Important

Les fichiers de test avec phpinfo() affichent les variables d'environnement. Qui transmet des secrets sous forme de variables d'environnement les révèle via un fichier de test oublié. Le contexte est décrit dans Fichiers phpinfo() : pourquoi ils doivent disparaître.

Après une intrusion : remplacer les identifiants

Aucun blocage ne protège contre un attaquant qui exécute déjà du code sur le serveur. Un processus PHP doit pouvoir lire sa configuration ; du code injecté dans le même processus le peut donc aussi. Après PHP2Shell, la règle est donc : si une intrusion ne peut pas être exclue, tous les identifiants présents sur le serveur doivent être traités comme connus.

Un remplacement ordonné comprend les mots de passe de base de données, les accès de messagerie et SMTP, les clés d'API des services externes, les clés de signature de l'application et les accès aux services de stockage. L'ordre et le moment doivent être planifiés : qui remplace d'abord puis nettoie ensuite le serveur donne peut-être du même coup les nouvelles valeurs à l'attaquant.

Vous limitez les dégâts d'une fuite dès en amont, en veillant à ce que chaque secret ne puisse faire que le nécessaire. L'utilisateur de base de données du site n'a pas besoin de droits sur d'autres bases de données. Chez de nombreux fournisseurs, les clés d'API de services externes peuvent être restreintes à certaines fonctions ou adresses d'expéditeur, par exemple créer des envois mais ne pas déclencher de paiements. Et chaque application reçoit ses propres accès, au lieu que plusieurs sites partagent le même compte de messagerie ou la même clé. Une fuite concerne alors un périmètre clairement délimité, et le remplacement reste maîtrisable.

Dans les environnements de conteneurs, le fichier .env n'a sa place ni dans l'image ni dans un registre accessible publiquement. Excluez-le via .dockerignore et ne transmettez les secrets qu'à l'exécution, par les mécanismes de la plateforme.

À long terme, il vaut la peine d'examiner des coffres de secrets centralisés, comme les recommande l'OWASP : les secrets en un seul endroit, avec journal d'accès, renouvellement régulier et validité aussi courte que possible.

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

  • Nous vérifions depuis l'extérieur si les fichiers de configuration, leurs copies et les fichiers cachés de vos sites sont accessibles.
  • Nous réorganisons webroot, blocages du serveur web et droits de fichier de façon que les secrets ne soient plus accessibles via HTTP.
  • Nous vérifions dans les dépôts et les déploiements la présence d'identifiants versionnés.
  • Après un incident, nous planifions et accompagnons le remplacement de tous les accès concernés dans le bon ordre.

Ces travaux font partie de notre durcissement de serveur pour serveurs web PHP.

Questions fréquentes

Un fichier .env situé dans le webroot est-il automatiquement public ?

Pas automatiquement, mais souvent. Qu'il soit accessible dépend de la configuration du serveur web. De nombreuses configurations par défaut ne protègent que les fichiers .htaccess, pas les autres fichiers commençant par un point. Un test avec curl lève le doute.

Les variables d'environnement sont-elles plus sûres qu'un fichier .env ?

Pas par principe. L'OWASP souligne que les variables d'environnement sont lisibles par tous les processus de l'utilisateur et peuvent apparaître dans les journaux ou les images mémoire. Elles évitent toutefois un fichier dans le webroot. Mieux vaut recourir à des coffres de secrets centralisés lorsque l'environnement les prend en charge.

Que faire si le fichier .env était accessible ?

Considérer tous les identifiants qu'il contient comme connus et les remplacer : base de données, messagerie, API, services de paiement, clés de l'application. Vérifier ensuite dans les journaux d'accès si le fichier a été appelé et, en présence de données personnelles, impliquer le délégué à la protection des données.

Le fichier .env a-t-il sa place dans le dépôt Git ?

Non. Au mieux, le dépôt contient un modèle sans valeurs réelles, par exemple .env.example. Le vrai fichier est exclu via .gitignore et mis à disposition séparément sur le serveur.

phpinfo() peut-il révéler des identifiants ?

Oui. phpinfo() affiche notamment les variables d'environnement et les variables du serveur. Si des secrets s'y trouvent, ils sont affichés avec le reste. Les fichiers de test avec phpinfo() n'ont donc jamais leur place sur un système accessible.

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