Aller au contenu principal

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 :

  1. exécuter whoami, puis sudo whoami, et vérifier que les deux résultats sont différents
  2. exécuter groups svc-sauvegarde et vérifier que equipe-tech apparaît dans la liste, mais pas sudo
  3. exécuter ls -l /etc/equipe-tech.conf et 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

info

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.

attention

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.

  1. Affichez les variables USER et HOME avec echo "$USER" et echo "$HOME", puis comparez USER avec le résultat de whoami.
  2. Définissez une variable ECOLE avec ECOLE="BTS SIO", affichez-la avec echo "ECOLE = $ECOLE", puis lancez un shell enfant avec bash -c 'echo "ECOLE = $ECOLE"'. Que constatez-vous ?
  3. 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 :

  1. Vérifiez avec printenv | grep DB_PASSWORD si le mot de passe est visible.
  2. Affichez les 5 dernières commandes de votre session avec history | tail -5. Que constatez-vous ?
  3. 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 :

  1. 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 avec ls -l.
  2. Essayez d'afficher le fichier avec votre compte (cat /etc/sauvegarde.env).
  3. 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.)

  1. 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_PASSWORD donne son numéro, history -d NUMÉRO la 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 :
    1. rappeler les voies d'exposition constatées à l'étape 2 (environnement, historique, processus enfants) ;
    2. présenter le fichier protégé de l'étape 3 (propriétaire, droits) et expliquer pourquoi il convient mieux ;
    3. répondre aux questions de la classe.
astuce

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 :

VariableRôleExemple
HOMEDossier personnel de l'utilisateur/home/etudiant
USERNom du compte connectéetudiant
PATHListe des dossiers où le shell cherche les commandes/usr/local/bin:/usr/bin:/bin
LANGLangue utilisée par les programmesfr_FR.UTF-8
info

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 :

TypeVisible dans le shell qui l'a crééeHéritée par les programmes lancés ensuite
Variable locale (NOM=valeur)OuiNon
Variable exportée (export NOM)OuiOui
attention

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 (ou env) l'affiche en clair, et tout programme lancé depuis la session en hérite.
  • L'historique des commandes : la commande export qui 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 par root.
attention

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 :

  1. Un fichier dédié, qui ne contient que ce secret (ou les secrets du seul service concerné).
  2. 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.
  3. 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.
InformationVariable d'environnement ?
LANG, EDITOR, PATHOui, c'est leur rôle
Nom du serveur de base de données, numéro de portOui (configuration non secrète)
Mot de passe, clé d'API, jeton d'accèsNon : fichier protégé (ou coffre-fort de secrets dans les grandes organisations)
astuce

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.


Test de mémorisation/compréhension​


Qu'est-ce qu'une variable d'environnement ?


Quelle commande affiche la liste des variables d'environnement exportées de votre session ?


D'après le TP (étape 1), pourquoi `bash -c 'echo "ECOLE = $ECOLE"'` n'affiche-t-il rien avant `export ECOLE` ?


Quel danger précis crée un `export DB_PASSWORD=...` appliqué à un mot de passe ?


D'après le TP (étape 2), où la commande `export DB_PASSWORD="..."` reste-t-elle enregistrée, mot de passe compris ?


D'après le TP (étape 3), pourquoi `cat /etc/sauvegarde.env` échoue-t-il avec votre compte, après `chown svc-sauvegarde:svc-sauvegarde` et `chmod 600` ?


Pourquoi vaut-il mieux lire un mot de passe dans un fichier protégé que l'écrire directement dans une commande (par exemple `mysql -pMotDePasse`) ?


Un collègue propose d'ajouter `export DB_PASSWORD=...` dans le `~/.bashrc` de chacun. Quel est le principal problème ?