Les pubs vous déplaisent ? Aller Sans pub Auj.

Fichiers .env — 6 erreurs qui mettent vos secrets sur GitHub

Mis à jour le

La plupart des fuites de fichiers .env ne proviennent pas d'attaquants — elles proviennent de développeurs qui ont poussé des fichiers avant que .gitignore ne soit configuré, ont livré un fichier .env.example avec des valeurs en production, ou ont laissé un framework intégrer silencieusement des secrets serveur dans du JavaScript client. Voici les 6 erreurs qui se produisent réellement.

Fichiers .env — 6 erreurs qui mettent vos secrets sur GitHub 1
ANNONCE · Supprimer ?

Le rapport sur l'extension des secrets de GitGuardian 2023 a découvert plus de 12 millions de secrets déposés dans des dépôts publics GitHub. La plupart n'ont pas été volés — ils ont été téléversés par des développeurs qui croyaient sincèrement avoir bien géré la situation. Ces sont les modèles responsables.

1. Ajout de .gitignore après le premier commit

.gitignore Pour arrêter de suivre un fichier déjà commis : Après cela, le fichier reste sur le disque, mais Git l'ignore à partir de maintenant. des fichiers ne sont pas pris en compte lors de la mise en stage. Dès qu'un fichier est suivi — même brièvement — il est intégré à l'histoire de git. Si vous avez créé .env, exécuté git add . && git commit, puis ajouté .env à .gitignore plus tard, le fichier est toujours présent dans tous les commits précédant ce changement.

Vérifiez s'il est déjà dans l'histoire :

git log --all -- .env

Si cela retourne des commits, les secrets sont dans l'histoire. Roté les identifiants d'abord. Ensuite, supprimez le fichier de l'histoire à l'aide de git-filter-repo (la solution recommandée au lieu de git filter-branch):

pip install git-filter-repo
git filter-repo --path .env --invert-paths

Poussez forcé vers tous les serveurs distants et informez les collègues de réclamer une nouvelle copie. Les commits existent dans chaque copie faite avant la suppression — y compris les systèmes CI automatisés qui ont récupéré le dépôt.

2. Copie de .env vers .env.example sans effacer les valeurs

Le flux standard : créer .env avec des valeurs réelles, puis le copier vers .env.example pour montrer aux collègues quelles clés le projet nécessite. L'erreur se produit lors de la copie.

cp .env .env.example copie tout — clés et valeurs. Et .env.example est censé être commité. C'est tout le point de ce fichier. Les valeurs réelles dans .env.example sont intentionnellement placées dans le dépôt.

❌ Ce qui se trouve dans git :

DATABASE_URL=postgres://admin:supersecretpassword@prod-db.example.com/appdb
STRIPE_SECRET_KEY=sk_live_51AbcDefGhiJklMnopQrstUvwx...
JWT_SECRET=my-actual-production-jwt-secret

✅ Ce que .env.example doit ressembler :

DATABASE_URL=postgres://user:password@localhost:5432/appdb
STRIPE_SECRET_KEY=sk_live_YOUR_KEY_HERE
JWT_SECRET=generate-a-random-secret-min-32-chars

Créer .env.example avec des valeurs de placeholder d'abord, le commit, puis le copier vers .env et remplir les identifiants réels — pas dans l'autre sens.

3. Journalisation de process.env dans les gestionnaires d'erreurs

Cela commence comme une « vérification rapide » lors d'un incident et ne disparaît jamais. Ou il se trouve dans un middleware générique qui semble inoffensif.

// Classic debug line that makes it to production
console.log('Starting with config:', process.env);

// Generic error handler that dumps everything
app.use((err, req, res, next) => {
  logger.error({ config: process.env, error: err.message });
  res.status(500).json({ error: 'Internal server error' });
});

process.env à l'exécution contient toutes les variables dotenv chargées, ainsi que des variables système. Transmettre l'ensemble de l'objet à un journal permet qu'il arrive dans votre agence de journalisation, votre service de suivi des erreurs (Sentry, Datadog, Rollbar), et potentiellement dans des emails ou webhooks d'alertes d'erreurs. Beaucoup de ces services transmettent leurs données à des tiers avec leurs propres contrôles d'accès.

Journalisez uniquement les valeurs spécifiques nécessaires à l'analyse :

logger.error({
  nodeEnv: process.env.NODE_ENV,
  appVersion: process.env.APP_VERSION,
  error: err.message,
  stack: err.stack
});

4. Intégration de secrets dans les couches d'images Docker

Deux modèles qui insèrent définitivement des secrets dans l'histoire des images Docker :

# Pattern 1: COPY bakes the entire .env into a layer
COPY .env .

# Pattern 2: ARG/ENV burns values into build metadata
ARG DATABASE_URL
ENV DATABASE_URL=$DATABASE_URL

Même si vous supprimez le fichier dans une couche ultérieure (RUN rm .env), la valeur reste lisible dans l'histoire de l'image. Tout utilisateur ayant accès à l'image peut exécuter :

docker history --no-trunc your-image:tag

et récupérer les valeurs ARG utilisées lors de la construction. Les secrets de Docker BuildKit sont l'outil correct — ils montent les secrets pendant la construction sans les écrire dans aucune couche :

# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=db_url     DATABASE_URL=$(cat /run/secrets/db_url) ./setup.sh

Pour la configuration en temps réel, injectez des variables d'environnement au démarrage du conteneur via docker run -e ou environment: dans Docker Compose en référencant les variables d'environnement hôtes — jamais des valeurs fixes, jamais COPY‘d fichiers secrets.

5. Utilisation de placeholders faibles qui sont livrés en production

JWT_SECRET=secret, SESSION_SECRET=keyboard cat, APP_KEY=changeme, ENCRYPTION_KEY=1234567890abcdef. Ces valeurs commencent comme des placeholders de développement et sont parfois jamais remplacées. Les attaquants qui forcent les signatures JWT essaient activement ces chaînes — elles sont incluses dans des listes spécifiques parce qu'elles apparaissent dans les recherches sur GitHub.

Un JWT signé avec HS256 et un secret faible peut être cassé hors ligne avec des outils comme c-jwt-cracker. Un seul jeton valide intercepté suffit à casser le secret et à produire des jetons arbitraires.

Les secrets doivent être cryptographiquement aléatoires, au minimum 32 octets. Les générer avant qu'ils soient nécessaires — l' Générateur de secrets d'environnement sur IO Tools produira des valeurs aléatoires correctes pour les secrets courants (.env) comme les clés JWT, les secrets de session, les clés API, sans nécessiter de configuration. Les définir dès le départ ; ne pas utiliser un placeholder et planifier de « les corriger avant la production ».

6. Les conventions des variables d'environnement des frameworks exposant des secrets au client

Plusieurs frameworks populaires utilisent des préfixes de noms de variables pour déterminer la visibilité client ou serveur. Si cela est mal fait, des secrets sont envoyés dans le bundle JavaScript à chaque navigateur qui charge votre application — en clair.

  • Next.js : Réinclure NEXT_PUBLIC_-préfixées sont intégrées côté client. Mais les secrets côté serveur s'échappent lorsqu'ils sont passés par getServerSideProps props — toute valeur retournée dans props est sérialisée dans le HTML de la page et est lisible dans la source.
  • Vite : Les variables préfixées VITE_ sont intégrées dans le JS côté client. L'utilisation de VITE_DATABASE_URL « pour la commodité » est une erreur que les développeurs font réellement.
  • Create React App : Tous REACT_APP_ les variables finissent dans le bundle côté client, sans exception. Il n'y a pas de runtime côté serveur CRA — tout ce qui est chargé va directement au navigateur.

Vérifiez après la construction en recherchant les valeurs connues des secrets dans le répertoire de sortie :

grep -r "sk_live_" ./dist
grep -r "sk_live_" ./.next/static

Si des correspondances apparaissent, ces secrets sont présents dans chaque onglet du navigateur. Roté-les immédiatement et effectuez une audit de ce qui a été intégré.

Un habitude à adopter dès le début

Avant de créer tout fichier qui contiendra des secrets, configurez .gitignore d'abord — pas comme une étape postérieure. Le premier commit dans tout nouveau dépôt doit être .gitignore et .env.example avec des valeurs de placeholder. Le .gitignore Générateur produira un fichier d'ignorer complet, spécifique au framework, en moins d'une minute.

Les six erreurs ci-dessus sont toutes évitables avant qu'aucun code ne soit écrit. La rotation est la seule solution une fois que les secrets sont exposés — et cela signifie que la rotation doit être effectuée partout : auprès du fournisseur de service, dans chaque environnement qui a une copie, et dans chaque système qui pourrait avoir stocké la valeur dans les journaux.

Envie d'une expérience sans pub ? Passez à la version sans pub

Installez nos extensions

Ajoutez des outils IO à votre navigateur préféré pour un accès instantané et une recherche plus rapide

Sur Extension Chrome Sur Extension de bord Sur Extension Firefox Sur Extension de l'opéra

Le Tableau de Bord Est Arrivé !

Tableau de Bord est une façon amusante de suivre vos jeux, toutes les données sont stockées dans votre navigateur. D'autres fonctionnalités arrivent bientôt !

ANNONCE · Supprimer ?
ANNONCE · Supprimer ?
ANNONCE · Supprimer ?

Coin des nouvelles avec points forts techniques

Impliquez-vous

Aidez-nous à continuer à fournir des outils gratuits et précieux

Offre-moi un café
ANNONCE · Supprimer ?