Bases de la sécurité
Votre fichier .env est-il exposé ? Les douze chemins à vérifier
Votre fichier .env est-il exposé sur votre propre serveur web ? Douze adresses vous le disent, et une réponse signifie que tout son contenu est public.

En bref
- Deux problèmes différents portent le même nom : un fichier .env exposé. Celui-ci, c’est le fichier lui-même posé sur votre serveur web, téléchargeable par quiconque tape l’adresse.
- Un hébergeur qui ne sert que votre frontend construit ne peut pas faire ça. Un vrai serveur, si, et c’est pourquoi sept des huit applications trouvées étaient des applications Replit.
- Sur 30 761 applications en ligne où notre vérification a obtenu une réponse, 8 remettaient un fichier privé. Douze adresses vous disent si vous êtes la neuvième.
Quelqu’un vous a dit que votre fichier .env est exposé, et la phrase ne vous
dit pas si c’est grave. Elle recouvre deux situations complètement différentes.
L’une, c’est l’outil qui fait ce pour quoi il est fait. L’autre signifie qu’un
fichier que vous croyiez privé se télécharge depuis votre site en ligne, par
n’importe qui, depuis le jour où il s’y trouve.
Voici la partie que guide après guide confond : une valeur de votre .env qui
finit dans votre JavaScript n’est pas le même événement que le fichier .env
lui-même servi par votre serveur web. Le premier, c’est le build qui fait ce
que vous avez demandé en nommant la variable VITE_QUELQUE_CHOSE. Le second est
une erreur de rangement, et c’est celui à vérifier d’abord, parce que vous pouvez
le vérifier vous-même depuis l’extérieur en une minute environ.
Voyez votre site en ligne comme le comptoir d’une boutique. Tout ce qui est sur
le comptoir est là pour être pris : la page, les images, le JavaScript, le logo.
L’arrière-boutique derrière contient ce qui fait tourner la maison, et un
visiteur n’a aucun chemin jusque-là. Une valeur compilée dans votre JavaScript
est une ligne imprimée sur le dépliant posé sur le comptoir. Le fichier .env
qui répond à une adresse publique, c’est le dossier de l’arrière-boutique, laissé
sur le comptoir avec le reste.
Mon fichier .env est-il exposé ?
Ouvrez votre site en ligne dans un navigateur, ajoutez /.env à la fin de
l’adresse et appuyez sur entrée.
Trois choses peuvent revenir, et une seule est un problème.
Une page de votre application. La plupart des frontends répondent à toute adresse inconnue par leur propre page d’index, parce que c’est ainsi qu’une application monopage fait son routage. Vous obtenez votre accueil, ou votre écran de page introuvable. Rien n’est servi sur ce chemin.
Une erreur. Un 403 ou un 404 signifie que le serveur a été interrogé et a refusé. C’est la réponse que vous voulez.
Du texte brut, avec des lignes dedans. Quelque chose comme
SUPABASE_URL=https://… et SUPABASE_SERVICE_ROLE_KEY=eyJ…, en bloc
monospacé sans aucune mise en forme. Le fichier est remis à qui le demande,
et cela depuis le jour où il a été servi pour la première fois.
Deux choses différentes s’appellent un fichier .env exposé
L’une concerne votre bundle. L’autre concerne votre serveur.
| Ce qui s’est passé | Où se trouve la valeur | Ce que coûte le remède |
|---|---|---|
Vous avez nommé une variable VITE_, NEXT_PUBLIC_ ou EXPO_PUBLIC_ | Compilée dans le JavaScript que télécharge chaque visiteur | Déplacer le travail sur un serveur, puis faire tourner la clé. Le fichier n’a jamais été servi. |
| Votre serveur web publie votre dossier de projet | Dans le fichier, à https://votresite/.env | Sortir le fichier de ce que le serveur publie, puis faire tourner tout son contenu. |
La première ligne est le cas courant et a son propre article : le préfixe est une instruction de publier, et le build l’a suivie. Tout ce qui suit ici est la seconde ligne.
Pourquoi une application Lovable ne peut pas et une Replit si
Parce que les deux hébergeurs publient des choses différentes.
Un builder qui déploie un frontend statique remet à son hébergeur un dossier de
fichiers construits : du HTML, du JavaScript, des images. Votre .env a été lu
pendant le build et n’est pas dans ce dossier, donc il n’y a rien à récupérer à
/.env. L’hébergeur ne pourrait pas servir le fichier même s’il le voulait.
Une application Replit fait en général tourner son propre serveur, dans son propre dossier de projet, vos fichiers à côté de votre code. Un serveur à qui l’on demande de servir son dossier sert tous les fichiers qui s’y trouvent, et il n’a aucun moyen de savoir que l’un d’eux contient vos clés. Cela vaut pour tout ce que vous avez déployé sur une machine à vous.
Les chiffres suivent l’architecture. Sur 30 761 applications en ligne où cette vérification a obtenu une réponse, 8 remettaient au moins un fichier privé. Sept des huit étaient des applications Replit, et les applications Replit étaient 3 025 des 30 761. La huitième était sur un domaine à elle, ce qui dit la même chose autrement : quelqu’un faisait tourner son propre serveur.
C’est la trouvaille la plus rare que nous imprimions, et la seule des neuf sans explication innocente. Si vous voulez la lecture large de ce que livrent réellement les applications Replit, nous en avons scanné 3 042.
Les douze chemins à vérifier
Douze adresses, dans l’ordre où cela vaut la peine. Mettez chacune après votre domaine.
| Adresse | Ce qu’elle contient | Si elle répond avec du texte |
|---|---|---|
/.env | Toutes les clés avec lesquelles l’app a été construite | Tout traiter comme public et faire tourner |
/.env.local | Pareil, depuis une exécution locale | Pareil |
/.env.production | Pareil, depuis votre déploiement en ligne | Pareil |
/.git/config | L’adresse distante de votre dépôt | Tout le répertoire .git est en général lisible |
/.git/HEAD | Sur quelle branche vous êtes | Pareil, et c’est le plus discret des douze |
/.aws/credentials | Des clés Amazon de longue durée | Faire tourner chez Amazon, puis regarder la facture |
/database.sql | Schéma et lignes | Toutes les lignes de toutes les tables sont publiques |
/dump.sql | Pareil | Pareil |
/backup.sql | Pareil | Pareil |
/config.json | Ce que vous y avez mis | Lisez-le et voyez ; il y a des jetons là plus souvent qu’on ne croit |
/docker-compose.yml | Des définitions de services, souvent avec des mots de passe | Faire tourner tout ce qui y est écrit |
/.npmrc | Un jeton de registre | Révoquer le jeton |
Notre propre scan lit les douze depuis l’extérieur et vous nomme celles qui ont répondu. Il prend une vingtaine de secondes et ne demande pas de compte : scannez votre application.
Ce qu’une réponse veut vraiment dire
Tout ce qui est dans ce fichier est public en ce moment, et l’est depuis le jour où il a été servi pour la première fois.
Vous ne saurez pas qui l’a lu. Un builder ne vous donne aucun journal de fichier récupéré que vous puissiez aller consulter, et la requête ressemble à n’importe quelle autre requête pour n’importe quel autre fichier. Ce dont vous pouvez être sûr, c’est que quelqu’un a essayé : des robots automatiques parcourent exactement ces douze chemins sur tout internet, en permanence, et ils n’ont pas besoin de savoir qui vous êtes pour trouver le vôtre.
Cinq des huit applications trouvées remettaient l’une des quatre qui coûtent
tout de suite : .env, un répertoire .git, .aws/credentials ou un dump
.sql. Les trois autres remettaient config.json, docker-compose.yml ou
.npmrc. Ces trois-là sont celles que tout le monde croit inoffensives, et c’est
exactement pour cela que des jetons et des mots de passe de base de données
finissent écrits dedans.
Ce que ceci n’est pas, c’est un verdict sur votre application. Une vérification externe lit ce que votre site remet à un inconnu, et douze chemins qui répondent avec rien sont douze chemins qui répondent avec rien. Ce qui s’échappe d’autre d’une application vibe-codée est la liste longue.
Celui qui gâche une semaine : un répertoire .git
Un répertoire .git n’est pas un fichier. C’est tout votre historique.
Chaque commit y est, y compris celui où vous avez collé une clé et le suivant où
vous l’avez retirée. C’est la partie que les gens comprennent de travers dans une
fuite .git : supprimer un secret du code d’aujourd’hui ne fait rien à la
version où il était encore là, et cette version se trouve dans le répertoire même
que votre serveur publie.
La vérification lit /.git/config et /.git/HEAD parce que ces deux-là sont
petits, que leur contenu ne trompe pas, et que l’un ou l’autre qui répond
signifie que le répertoire lui-même est servi. À partir de là, un lecteur n’a
besoin d’aucun outil particulier. Le format est documenté et un logiciel
ordinaire le clone.
Si une clé a été dans un commit un jour, la faire tourner est la seule chose qui aide. Laquelle d’abord dépend de si la copie est déjà sortie, et cet ordre mérite d’être juste.
Le dump que quelqu’un a laissé dans le dossier
Trois des douze chemins sont des dumps de base de données : /database.sql,
/dump.sql et /backup.sql.
Un dump, c’est toutes les lignes de toutes les tables dans un fichier, avec le schéma au-dessus. Des adresses e-mail, des mots de passe hachés, des commandes, des messages, tout ce que votre application conserve. Il répond à une adresse publique pour la raison la plus terne de tout cet article : quelqu’un a fait la chose responsable, a pris une copie de sa base de données, et l’a enregistrée dans le dossier de projet où il se trouvait.
Ainsi le fichier fait pour protéger les données est devenu le moyen le plus rapide de toutes les lire. Où vit une copie fait autant partie de la décision que le fait d’en prendre une. Trois façons de sauvegarder une base de données Supabase passe les options en revue, et Reeve Care garde une copie de votre base de données Supabase hors de votre propre serveur, vérifiée avant de compter comme sauvegarde.
Comment le corriger, et pourquoi l’ordre compte
Sortez le fichier de ce que votre serveur publie. Faites tourner ensuite chaque secret qu’il contenait. Dans cet ordre.
Faire tourner d’abord a l’air de la moitié urgente, et c’est la moitié qui gaspille le travail. Vos nouvelles clés vont dans le même fichier, le fichier répond toujours à la même adresse, et vous avez fait tourner droit dans la fuite. Rien n’est plus sûr qu’il y a dix minutes.
Où le mettre à la place, selon ce que vous faites tourner :
- Un hébergeur avec son propre coffre à secrets. Replit Secrets, les variables d’environnement d’une plateforme, votre tableau de bord d’hébergement. La valeur est lue par votre serveur à l’exécution et ne se trouve jamais dans un fichier sous le dossier publié.
- En dehors du dossier servi. Si vous contrôlez la configuration du serveur, pointez-la sur un dossier de sortie de build plutôt que sur la racine du projet. Un fichier à la racine n’a alors aucune adresse.
- Pas non plus dans le dépôt, ce qui est une habitude à part et une bonne. Pour le problème d’aujourd’hui, cela ne fait rien.
Ce dernier point vaut d’être dit clairement, parce que .gitignore est la
réponse vers laquelle tout le monde va. Il garde le fichier hors de votre dépôt.
Le fichier sur votre serveur y est arrivé parce que le serveur est assis dans
votre dossier de projet, et git n’a pas d’avis là-dessus.
Quoi faire tout de suite
Que faire
- Tapez les douze adresses derrière votre propre domaine, ou lancez le scan gratuit et laissez-le taper. Lisez ce qui revient, pas le code de statut.
- Si l’une répond avec vos propres réglages, sortez le fichier du dossier que votre serveur publie, et redéployez. C’est l’étape qui arrête la chose.
- Faites tourner ensuite chaque clé, mot de passe et jeton que le fichier contenait, chez chaque fournisseur. Faire tourner avant de déplacer le fichier remet les nouvelles valeurs là où étaient les anciennes.
- Regardez la facturation et les journaux du fournisseur après. Faire tourner arrête ce qui vient ensuite et ne fait rien à ce qui s’est déjà passé.
- Si un répertoire
.gitétait lisible, faites tourner tout ce qui a été dans un commit un jour, pas seulement ce qui est dans le code aujourd’hui.
Si vous préférez parcourir votre application comme une liste, la checklist de sécurité en 10 minutes couvre ceci à côté des autres choses à fermer dans une application fraîchement lancée.
FAQ
Comment savoir si mon fichier .env est public ?
Ouvrez votre site en ligne dans un navigateur, ajoutez /.env à la fin de l’adresse et appuyez sur entrée. Si une page de votre application revient, rien n’est servi sur ce chemin. Si du texte brut revient, avec des lignes comme SUPABASE_URL=https://abcdefghij.supabase.co, le fichier est remis à qui le demande. Faites pareil avec /.env.local et /.env.production, car un serveur qui publie l’un publie souvent les trois.
Un fichier .env dans mon bundle, c’est pareil ?
Non, et le remède est différent. Une valeur qui finit dans votre JavaScript y est arrivée parce qu’on l’a demandé au build, avec une variable nommée VITE_ ou NEXT_PUBLIC_ ou EXPO_PUBLIC_. Le fichier n’a jamais quitté votre machine ; la valeur, si. C’est un problème distinct avec son propre article. Ici il s’agit du fichier lui-même, servi par votre serveur web, ce qui rend publique chacune de ses valeurs, préfixée ou non.
Pourquoi quelqu’un peut-il télécharger mon dossier .git ?
Parce que votre serveur pointe sur votre dossier de projet et que .git est un répertoire à l’intérieur comme un autre. Un serveur ignore que l’un d’eux est votre historique de versions. Si /.git/config ou /.git/HEAD répond avec du texte, tout le répertoire est en général lisible, et cela comprend chaque commit que vous avez fait, pas seulement le code d’aujourd’hui.
J’ai trouvé un backup.sql sur mon propre site, et maintenant ?
Sortez-le du dossier que votre serveur publie avant toute autre chose, car le fichier est remis pendant que vous lisez ces lignes. Traitez ensuite chaque mot de passe, chaque clé et chaque donnée personnelle qu’il contient comme publics : un dump porte le schéma et toutes les lignes de toutes les tables. Puis cherchez comment il est arrivé là, en général quelqu’un a fait une copie dans le dossier du projet et ne l’a jamais déplacée.
Je fais tourner les clés ou je supprime le fichier d’abord ?
Déplacez le fichier d’abord, faites tourner ensuite. Faire tourner pendant que le fichier est encore servi écrit les nouvelles valeurs dans quelque chose que n’importe qui télécharge, donc vous dépensez l’effort et vous revenez au point de départ. Une fois que plus rien ne répond sur ce chemin, faites tourner chaque secret du fichier, chez chaque fournisseur, et regardez la facturation et les journaux après.