Aller au contenu

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.

Vlad Tkachenko10 min de lecture
Quatre dossiers scellés derrière un mur et, devant, un dossier ouvert dont les lignes sont visibles sous un bandeau ambre.

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 valeurCe 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 visiteurDé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 projetDans le fichier, à https://votresite/.envSortir 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.

À gauche : le build a copié une valeur dans votre JavaScript, parce que le préfixe le lui demandait. À droite : le serveur remet le fichier, et les préfixes n’y changent rien.

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.

AdresseCe qu’elle contientSi elle répond avec du texte
/.envToutes les clés avec lesquelles l’app a été construiteTout traiter comme public et faire tourner
/.env.localPareil, depuis une exécution localePareil
/.env.productionPareil, depuis votre déploiement en lignePareil
/.git/configL’adresse distante de votre dépôtTout le répertoire .git est en général lisible
/.git/HEADSur quelle branche vous êtesPareil, et c’est le plus discret des douze
/.aws/credentialsDes clés Amazon de longue duréeFaire tourner chez Amazon, puis regarder la facture
/database.sqlSchéma et lignesToutes les lignes de toutes les tables sont publiques
/dump.sqlPareilPareil
/backup.sqlPareilPareil
/config.jsonCe que vous y avez misLisez-le et voyez ; il y a des jetons là plus souvent qu’on ne croit
/docker-compose.ymlDes définitions de services, souvent avec des mots de passeFaire tourner tout ce qui y est écrit
/.npmrcUn jeton de registreRé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.

Faites tourner d’abord et la nouvelle clé atterrit dans le fichier encore remis. Déplacez d’abord et il ne reste rien à remettre.

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.

Écrit par

Vlad Tkachenko

Fondateur de Reeve

Je passe mes journées à examiner des applications créées avec Lovable, Bolt, v0, Cursor et Replit, et la courte liste d'erreurs qui y reviennent sans cesse.

En savoir plus sur l'auteur

À lire ensuite

Tous les articles

Vous ne savez pas où en est votre propre application ?

Lancez une analyse gratuite et obtenez une note claire de A à F en une vingtaine de secondes. Sans compte, sans carte.

Analyser mon application

Vérification externe automatisée, pas un audit complet. L'absence de problème n'est pas une garantie de sécurité.