Les variables d'environnement contiennent-elles des secrets ?
Ne jamais exposer un mot de passe
Petite vérification
Avant de commencer, vérifiez si vous savez encore réaliser ces 3 actions très simples, sur la séance précédente consacrée au principe du moindre privilège :
- exécuter
whoami, puissudo whoami, et vérifier que les deux résultats sont différents - exécuter
groups svc-sauvegardeet vérifier queequipe-techapparaît dans la liste, mais passudo - exécuter
ls -l /etc/equipe-tech.confet relever le propriétaire du fichier
📌 Réponse attendue
TP pour réfléchir et résoudre des problèmes
Votre défi pour aujourd'hui consiste à repérer par où fuit un mot de passe rangé dans une variable d'environnement, puis à lui trouver une meilleure place
Ce TP nécessite les droits sudo sur votre serveur Linux, ainsi que le compte de service
svc-sauvegarde créé lors de la séance sur le moindre privilège.
Le mot de passe Sauvegarde-2025! utilisé dans ce TP est fictif. N'utilisez jamais un vrai mot
de passe dans un exercice.
Étape 1 — Découvrir les variables d'environnement
Une variable d'environnement est une valeur nommée, rattachée à un programme en cours
d'exécution. Votre session en contient déjà beaucoup. Pour la suite, deux commandes vous seront
utiles : echo "$NOM" affiche le contenu d'une variable, et export NOM la rend visible des
programmes lancés depuis votre session.
- Affichez les variables
USERetHOMEavececho "$USER"etecho "$HOME", puis comparezUSERavec le résultat dewhoami. - Définissez une variable
ECOLEavecECOLE="BTS SIO", affichez-la avececho "ECOLE = $ECOLE", puis lancez un shell enfant avecbash -c 'echo "ECOLE = $ECOLE"'. Que constatez-vous ? - Exportez-la avec
export ECOLE, puis relancez le même shell enfant. Que constatez-vous ?
📌 Réponse attendue
Étape 2 — Constater où fuit un mot de passe exporté
Camille, qui a configuré la sauvegarde, a procédé ainsi pour que le script retrouve son mot de passe de base de données : elle l'a simplement exporté dans sa session.
export DB_PASSWORD="Sauvegarde-2025!"
Reproduisez cette commande dans votre session, puis :
- Vérifiez avec
printenv | grep DB_PASSWORDsi le mot de passe est visible. - Affichez les 5 dernières commandes de votre session avec
history | tail -5. Que constatez-vous ? - Lancez un programme quelconque depuis votre session, puis lisez son environnement :
sleep 300 &
PID=$!
tr '\0' '\n' < /proc/$PID/environ | grep DB_PASSWORD
sudo -u svc-sauvegarde cat /proc/$PID/environ
kill $PID
(tr '\0' '\n' remplace le séparateur interne du fichier environ par des retours à la ligne,
pour le rendre lisible.) Que constatez-vous pour la 3e ligne, puis pour la 4e ?
📌 Réponse attendue
Étape 3 — Ranger le secret dans un fichier protégé
Le script de sauvegarde s'exécute avec le compte svc-sauvegarde. Il lui faut le mot de passe, mais
personne d'autre n'a à pouvoir le lire. Créez un fichier dédié, en passant par nano pour que le
mot de passe n'apparaisse pas dans l'historique de votre session :
cd /tmp
sudo nano /etc/sauvegarde.env
Dans nano, écrivez la ligne DB_PASSWORD=Sauvegarde-2025!, puis enregistrez (Ctrl+O, Entrée,
Ctrl+X). Ensuite :
- Donnez la propriété du fichier à l'utilisateur et au groupe
svc-sauvegarde, puis ne laissez les droits de lecture et d'écriture qu'au propriétaire (notation octale). Vérifiez avecls -l. - Essayez d'afficher le fichier avec votre compte (
cat /etc/sauvegarde.env). - Vérifiez que le compte de service peut s'en servir, sans jamais afficher le mot de passe :
sudo -u svc-sauvegarde bash -c '. /etc/sauvegarde.env && echo "Mot de passe chargé : ${#DB_PASSWORD} caractères"'
(${#DB_PASSWORD} donne le nombre de caractères de la variable, pas son contenu.)
- Nettoyez votre session : supprimez la variable
DB_PASSWORD, vérifiez qu'elle a bien disparu, puis retirez de l'historique la ligne qui contenait le mot de passe (history | grep DB_PASSWORDdonne son numéro,history -d NUMÉROla supprime).
📌 Réponse attendue
Étape 4 — Réagir à un cas pratique
Un collègue propose : « pour que le script retrouve toujours son mot de passe, on n'a qu'à ajouter
export DB_PASSWORD="Sauvegarde-2025!" dans le fichier ~/.bashrc de chacun, comme ça la variable
est toujours disponible ». Que lui répondez-vous ?
Restitution orale
Un étudiant (ou un binôme) vient présenter au tableau les 3 endroits où le mot de passe a fui à l'étape 2, la solution retenue à l'étape 3 et sa réponse au collègue de l'étape 4.
- Durée : 5 minutes de présentation + 2 à 3 minutes de questions.
- Qui passe : un(e) étudiant(e) (ou un binôme) désigné(e) par l'enseignant.
- Support : le travail réalisé pendant le TP, aucune préparation supplémentaire n'est nécessaire.
- Ce qui est attendu :
- rappeler les voies d'exposition constatées à l'étape 2 (environnement, historique, processus enfants) ;
- présenter le fichier protégé de l'étape 3 (propriétaire, droits) et expliquer pourquoi il convient mieux ;
- répondre aux questions de la classe.
Cet exercice entraîne à l'oral technique court exigé par plusieurs épreuves du BTS (notamment E5 et E6) : clarté, structure, capacité à répondre à l'improviste.
📌 Une solution
Notions théoriques
Vous venez de constater qu'un mot de passe confié à une variable d'environnement se retrouve à plusieurs endroits, que vous n'aviez pas prévus.
Qu'est-ce qu'une variable d'environnement ?
Une variable d'environnement est une paire NOM=valeur rattachée à un processus (un programme
en cours d'exécution). Lorsqu'un programme en lance un autre, le nouveau programme reçoit une
copie de cet environnement : on dit qu'il en hérite.
Quelques variables que vous avez déjà rencontrées sans les nommer :
| Variable | Rôle | Exemple |
|---|---|---|
HOME | Dossier personnel de l'utilisateur | /home/etudiant |
USER | Nom du compte connecté | etudiant |
PATH | Liste des dossiers où le shell cherche les commandes | /usr/local/bin:/usr/bin:/bin |
LANG | Langue utilisée par les programmes | fr_FR.UTF-8 |
Si vous avez déjà rencontré un fichier .env dans le cours PHP, c'est exactement la même idée :
des réglages (parfois des secrets) mis à disposition d'un programme sans les écrire dans son code.
Variable locale et variable exportée
À l'étape 1, la variable ECOLE n'était pas transmise au shell enfant avant export. Cette
différence est essentielle :
| Type | Visible dans le shell qui l'a créée | Héritée par les programmes lancés ensuite |
|---|---|---|
Variable locale (NOM=valeur) | Oui | Non |
Variable exportée (export NOM) | Oui | Oui |
export est donc exactement ce qui rend un secret dangereux : plus la variable est largement
exportée, plus nombreux sont les programmes qui la reçoivent, y compris ceux qui n'en ont pas besoin
et ceux qui sont malveillants.
Pourquoi une variable d'environnement n'est pas un coffre-fort
Une variable d'environnement n'est pas conçue pour garder un secret. À l'étape 2, vous avez vu 3 voies d'exposition :
- L'environnement lui-même :
printenv(ouenv) l'affiche en clair, et tout programme lancé depuis la session en hérite. - L'historique des commandes : la commande
exportqui définit le mot de passe est conservée telle quelle dans l'historique du shell, puis dans~/.bash_history. - Le processus enfant : l'environnement d'un programme est lisible dans
/proc/PID/environ, par son propriétaire et parroot.
Le même problème existe quand on écrit un mot de passe directement dans une commande
(par exemple mysql -pMotDePasse) : les arguments d'un programme sont visibles par les autres
utilisateurs du serveur, avec des commandes comme ps. Un secret ne doit jamais figurer sur une
ligne de commande.
Où ranger un secret à la place
La bonne approche, appliquée à l'étape 3, tient en 3 règles :
- Un fichier dédié, qui ne contient que ce secret (ou les secrets du seul service concerné).
- Des droits minimaux : propriétaire = le compte de service qui l'utilise, droits
600, aucun accès pour les autres comptes. C'est le moindre privilège appliqué à un fichier. - Une lecture au dernier moment : le script lit le fichier lui-même, au moment où il en a besoin, sans l'exporter dans l'environnement de toute la session.
| Information | Variable d'environnement ? |
|---|---|
LANG, EDITOR, PATH | Oui, c'est leur rôle |
| Nom du serveur de base de données, numéro de port | Oui (configuration non secrète) |
| Mot de passe, clé d'API, jeton d'accès | Non : fichier protégé (ou coffre-fort de secrets dans les grandes organisations) |
Un fichier de secrets n'a pas non plus sa place dans un dépôt de code partagé : c'est une autre façon, très fréquente, de faire fuir un mot de passe, étudiée dans une séance à venir.