Vibe Coding — ton premier app sans savoir coder — 9. Déboguer comme un pro & sécuriser ton app

20 min read min de lecture
Chapitre 09

Déboguer comme un pro & sécuriser ton app

Chapitre 9 sur 10 · 90%

Objectifs de ce chapitre

  • Protéger tes secrets et réagir correctement à une fuite
  • Valider les entrées utilisateur et poser des limites partout
  • Diagnostiquer méthodiquement un bug en production

Le soir où tout a failli déraper

Un mardi soir, deux messages tombent coup sur coup. Le premier vient de Karim, un élève à l'humour douteux : « M'sieur, j'ai mis un truc bizarre dans le nom d'une habitude et maintenant la page affiche n'importe quoi 😂 ». Le second vient de la collègue de français : « L'app était très lente hier vers 19 h, c'est normal ? ». Tom réalise une chose que tout créateur d'app découvre un jour : avec de vrais utilisateurs viennent les vrais bugs… et les vraies bêtises. Son app n'est plus un projet personnel, c'est un service public miniature — et un service, ça se sécurise.

Rassure-toi : la sécurité « niveau débutant pro » tient sur trois fronts, et tu as déjà des bases sur chacun. Les secrets (tes clés et mots de passe d'infrastructure), les entrées (tout ce que les utilisateurs tapent), et les limites (ce qu'on a le droit de faire, combien de fois). Ce chapitre fait le tour des trois, puis t'arme pour le débogage en conditions réelles — celui où le bug est chez un utilisateur, sur un appareil que tu n'as pas, à une heure où tu n'étais pas là.

Front 1 — Les secrets

Tu sais déjà que les clés vivent dans un fichier .env côté serveur. Reste à vérifier deux choses. D'abord, que ce fichier est bien ignoré par Git : s'il est commité, il part sur GitHub avec le reste — et un dépôt, même privé aujourd'hui, peut devenir public demain. Ensuite, que tu sais réagir à une fuite : on ne « cache » jamais une clé compromise, on la révoque (on la désactive dans le tableau de bord du service) et on en génère une nouvelle. Toujours, sans exception, même dans le doute.

bash
# .gitignore — à la racine du projet
.env
.env.local

# Vérifier que .env n'est PAS suivi par Git :
git status
# .env ne doit apparaître nulle part dans la sortie.

# Si une clé a fuité : on ne la cache pas, on la RÉVOQUE
# dans le tableau de bord du service, et on en génère une nouvelle.
Une clé poussée sur GitHub est compromise définitivement, même si tu la supprimes au commit suivant : l'historique Git garde tout, et des robots scannent les dépôts publics en permanence — une clé exposée est typiquement testée en quelques minutes. Le seul remède est la révocation immédiate. Supprimer le fichier ne répare rien.

Front 2 — Ne jamais faire confiance aux entrées

Revenons à la blague de Karim. Qu'a-t-il fait ? Il a tapé du code HTML dans le champ « nom d'habitude » — quelque chose comme <h1>COUCOU</h1> — et l'app l'a affiché tel quel, en l'interprétant comme de la mise en page. Drôle ici ; grave en général : si une app affiche sans précaution ce que les utilisateurs saisissent, un utilisateur malveillant peut y glisser du code qui s'exécutera chez les autres. C'est la famille d'attaques la plus courante du web (les initiés disent « XSS »), et la parade s'appelle l'échappement : le texte saisi est toujours affiché comme du texte, jamais interprété comme du code.

Le principe à graver : toute entrée utilisateur est suspecte par défaut. Un nom d'habitude doit être traité comme du texte brut, vérifié en longueur, et validé côté serveur — pas seulement dans le navigateur, car un utilisateur outillé peut contourner tout ce qui se passe côté client. Tu n'as pas à implémenter ça toi-même : tu dois l'exiger et le tester. Le test est simple et savoureux : fais comme Karim, essaie de casser ta propre app.

L’audit de sécurité : ton allié IA

Bonne nouvelle : l'IA est remarquablement douée pour auditer le code qu'elle a elle-même écrit, à condition de lui donner un mandat précis. Voici le prompt d'audit de Tom — garde-le précieusement, il resservira à chaque étape importante de tous tes projets :

PROMPT
Fais un audit de sécurité complet de mon app de suivi d'habitudes, adapté à mon niveau débutant.
Contexte : HTML/JS sur Vercel, Supabase avec authentification par lien magique et règles RLS, fonctions serveur pour les e-mails et l'IA, paiement via Stripe Payment Links.
Vérifie en priorité :
1. des clés ou secrets présents dans le code côté navigateur, dans le dépôt Git ou dans son historique
2. les entrées utilisateur affichées sans échappement : noms d'habitudes, contenus de formulaires
3. les règles RLS : un utilisateur peut-il lire ou modifier les données d'un autre ?
4. les fonctions serveur : peuvent-elles être appelées sans être connecté ? sans limite de fréquence ?
5. les dépendances ou bibliothèques avec des failles connues
Pour chaque problème trouvé : explique le risque en une phrase simple, montre la correction minimale, et classe le tout par gravité de critique à mineur.
Ne corrige RIEN sans mon accord explicite, point par point.

Deux exigences font la valeur de ce prompt. Le classement par gravité : tu traites d'abord le critique, et tu décides en connaissance de cause pour le reste — toutes les failles ne se valent pas, et un débutant qui veut tout corriger d'un coup ne corrige rien de bien. Et le « ne corrige rien sans mon accord » : un audit qui modifie le code en même temps qu'il l'analyse est incontrôlable. D'abord comprendre, ensuite corriger, une correction à la fois — la méthode du chapitre 4 s'applique aussi à la sécurité.

Front 3 — Poser des limites partout

Troisième front, le plus simple à comprendre : tout ce qui n'a pas de limite explicite finira par être poussé à l'absurde — par malice, par accident, ou par un robot. Au chapitre 8, tu as limité les e-mails et les appels IA ; généralise maintenant le réflexe à toute l'app. Chaque champ a une longueur maximale, chaque liste a une taille maximale, chaque action a une fréquence maximale. Et chaque refus s'accompagne d'un message poli et clair — la limite protège, elle ne punit pas.

  • Nom d'habitude : 50 caractères maximum, texte brut uniquement.
  • Nombre d'habitudes par compte : 30 maximum — personne n'en suit 200, mais un script peut en créer 100 000.
  • Récap e-mail : 1 envoi par utilisateur et par jour.
  • Message IA : 1 appel par utilisateur et par jour, plafond de dépense mensuel chez le fournisseur.
  • Création de compte : protégée par la vérification d'e-mail du lien magique — déjà en place, merci le chapitre 6.
flowchart TD
  E["Entrée ou action utilisateur"] --> V{"Contenu valide ?"}
  V -->|"Non"| R["Message d'erreur clair et poli"]
  V -->|"Oui"| L{"Dans les limites ?"}
  L -->|"Non"| R2["Refus expliqué : limite atteinte"]
  L -->|"Oui"| S["Traitement et stockage en sécurité"]
Le double filtre : on valide le contenu, puis on vérifie les limites — avant tout traitement.

Déboguer en production : la méthode

Reste le message de la collègue : « c'était lent hier vers 19 h ». Bug typique de production : tu ne l'as pas vu, tu ne peux pas le reproduire à volonté, et l'utilisateur ne donne presque aucun détail. La méthode pro tient en trois mouvements : collecter (poser à l'utilisateur les bonnes questions : quel appareil, quel navigateur, quelle heure, quelle action précise, une capture d'écran), consulter (les journaux — « logs » — de Vercel et Supabase, qui enregistrent ce qui s'est réellement passé sur le serveur à cette heure-là), et conjecturer (formuler des hypothèses classées, puis les tester une à une, de la plus simple à la plus complexe).

PROMPT
Bug en production à diagnostiquer méthodiquement.
Contexte : un élève me dit que l'app « efface ses coches » sur son téléphone Android avec Chrome, hier vers 19 h. Sur mon ordinateur, impossible de reproduire.
Ce dont je dispose : les logs Vercel de la soirée, l'accès au tableau de bord Supabase, et la possibilité de réécrire à l'élève.
Guide-moi en trois temps :
1. la liste exacte des questions à poser à l'élève pour cerner le contexte
2. quoi chercher précisément dans les logs Vercel et dans les données Supabase autour de 19 h
3. comment simuler un mobile Android et un réseau lent depuis mon navigateur pour tenter de reproduire
Propose ensuite tes 3 hypothèses les plus probables, classées de la plus simple à vérifier à la plus complexe, avec le test à faire pour chacune.

Remarque la structure : ce prompt ne demande pas une solution, il demande une enquête. C'est le bon réflexe face à un bug non reproduit — chercher la correction avant d'avoir cerné la cause, c'est corriger au hasard. Les « 3 hypothèses classées » t'évitent l'autre piège : explorer la piste exotique avant la piste banale. Dans la vraie vie, l'hypothèse banale gagne neuf fois sur dix : un réseau qui coupe au mauvais moment, une vieille version en cache, une session expirée.

Tiens un journal des incidents : un fichier texte avec, pour chaque bug, cinq lignes — date, symptôme, cause trouvée, correctif, leçon. Au dixième incident, tu verras des motifs se répéter, et tu sauras par où commencer chaque nouveau diagnostic. C'est l'outil le plus rentable de ce chapitre, et il ne coûte que deux minutes par bug.

La sauvegarde, ton assurance-vie

Dernière pièce du dispositif : la sauvegarde des données. Ton code est en sécurité dans Git, mais les habitudes et les coches de tes utilisateurs ne vivent que dans la base. Une fausse manœuvre dans le tableau de bord — une table vidée d'un clic trop rapide — et tout disparaît. Vérifie ce que ton plan Supabase sauvegarde automatiquement, et complète avec un export régulier (l'IA peut te créer un petit script d'export, ou utilise la fonction d'export du tableau de bord). Et surtout, fais une fois l'exercice de restauration : une sauvegarde jamais testée est une promesse, pas une protection.

Avec ses trois fronts couverts, son journal d'incidents entamé et sa première sauvegarde testée, Tom dort mieux. Karim a reçu un message poli (« nom d'habitude invalide 😉 »), la lenteur de 19 h s'est révélée être un réseau d'internat saturé — hypothèse banale, comme prévu. L'app est solide. Il est temps de la regarder autrement : non plus comme un projet, mais comme un produit. C'est le chapitre final.

🛠️ À toi de jouer

Contexte

Tom consacre une soirée complète à la revue de sécurité : audit par l'IA, corrections par gravité, limites partout, et premier test de restauration de sauvegarde. En prime, il s'offre le plaisir de jouer les Karim : essayer de casser sa propre app avant que quelqu'un d'autre ne s'en charge. Déroule le même programme sur ton app — c'est la soirée la plus rentable de ton parcours.

Consignes

  1. Vérifie tes secrets : .env dans le .gitignore, git status propre, et recherche « key » dans les sources côté navigateur (F12).
  2. Joue les attaquants : tape du HTML dans tes champs, des textes de 5000 caractères, clique frénétiquement — note tout ce qui casse.
  3. Lance le prompt d’audit de sécurité complet et lis le rapport en entier avant de corriger quoi que ce soit.
  4. Corrige les problèmes par gravité décroissante, UNE correction à la fois, avec test et commit après chacune.
  5. Pose tes limites (longueurs, quantités, fréquences) avec des messages de refus polis, et teste chaque limite.
  6. Exporte une sauvegarde de ta base, puis fais l’exercice de restauration sur un projet de test — et note la procédure dans ton journal.
Indice — Si l'audit remonte beaucoup de problèmes, ne panique pas : c'est normal pour une première fois, et c'est le but. Traite les « critiques » ce soir, planifie les « moyens » sur la semaine, et note les « mineurs » dans ta liste « plus tard ». La sécurité est un processus, pas un examen.

En résumé

  • Trois fronts : les secrets, les entrées utilisateur, les limites — couvre les trois et tu élimines l’essentiel du risque.
  • Une clé qui a touché Git est compromise pour toujours : on révoque et on régénère, on ne « cache » jamais.
  • Toute entrée utilisateur est suspecte : échappée à l’affichage, validée côté serveur, limitée en longueur.
  • L’audit IA fonctionne avec un mandat précis : périmètre, classement par gravité, et aucune correction sans ton accord.
  • Chaque champ, liste et action reçoit une limite explicite, avec un message de refus poli.
  • Bug en production : collecter le contexte, consulter les logs, conjecturer des hypothèses classées du banal vers l’exotique.
  • Une sauvegarde jamais restaurée est une promesse, pas une protection : teste la restauration une fois.

Quiz — vérifie ta compréhension

1. Tu découvres qu’une clé API a été poussée sur GitHub il y a une semaine. Que fais-tu ?

L'historique Git garde tout et les dépôts sont scannés par des robots en permanence : la clé est compromise définitivement. Seule la révocation répare — la suppression du fichier ne fait que cacher la trace.

2. Karim tape du HTML dans un champ et la page l’interprète. Comment s’appelle la parade ?

Afficher les saisies sans échappement ouvre la porte aux attaques de type XSS, où du code injecté s'exécute chez les autres utilisateurs. Texte saisi = texte affiché, toujours.

3. Pourquoi valider les entrées côté serveur et pas seulement dans le navigateur ?

Le code du navigateur est entre les mains de l'utilisateur : il peut le modifier ou l'ignorer. La validation serveur est la seule qui fait autorité — celle du navigateur n'est qu'un confort d'interface.

4. Quelles sont les deux exigences clés du prompt d’audit de sécurité ?

Le classement te fait traiter le critique d'abord ; l'accord explicite garde le contrôle. Un audit qui modifie le code pendant qu'il l'analyse est incontrôlable.

5. Un utilisateur signale un bug que tu ne peux pas reproduire. Par quoi commences-tu ?

Collecter, consulter, conjecturer : corriger avant d'avoir cerné la cause, c'est corriger au hasard. Et l'hypothèse banale (réseau, cache, session) gagne neuf fois sur dix.

Auteur(s)

R

REHOUMA Haythem

Haythem Rehouma est un ingénieur et architecte IA et cloud, formateur et enseignant technique, avec un profil orienté IA médicale, AWS, MLOps, LLM/RAG et vision par ordinateur.