Fuites
Ce que votre page d'accueil laisse voir qu'elle ne devrait pas — lorem ipsum, localhost, adresse de préproduction, clé secrète — et comment PostShip le lit.
Mis à jour le 11 septembre 2026
Sur cette page
- Ce que PostShip vérifie
- Les manques (le contrôle échoue)
- Les avertissements (le contrôle passe)
- Le rapport
- Régler
- Ce qui déclenche une alerte
- Limites et plans
- Dépannage
- Pourquoi « url_de_preprod » alors que mon site est hébergé sur Vercel ?
- Pourquoi « mot_de_chantier » sur une page qui n'a pas de TODO ?
- Pourquoi la clé anon de Supabase n'est-elle pas signalée ?
Une mise en ligne se fait souvent depuis une branche de travail : le gabarit garde un « Lorem ipsum » dans une section oubliée, une variable d'environnement pointe encore sur localhost:3000, une clé secrète Stripe copiée « pour tester » finit dans le bundle. Rien de tout cela ne fait tomber le site — les autres contrôles passent — et c'est un client, ou un inconnu qui lit le code source, qui le voit en premier. Ce contrôle lit le HTML de la page d'accueil à chaque déploiement et nomme ce qui a fui.
Ce que PostShip vérifie
Une lecture statique de la page d'accueil (jusqu'à 512 Ko) : ni ce que le JavaScript ajoute, ni les bundles externes. Deux régimes, comme pour le contenu attendu : les mots de maquette et de chantier ne comptent que dans le texte qu'un visiteur lit — un TODO dans un commentaire HTML n'est visible de personne ; les URL et les secrets se cherchent dans tout le HTML servi, parce que c'est là qu'ils fuient.
Les manques (le contrôle échoue)
| Code | Ce qui est lu |
|---|---|
texte_de_maquette | « lorem ipsum » dans le texte visible. |
url_locale | Une ressource ou un lien vers localhost, 127.0.0.1, 0.0.0.0, [::1], un hôte en .local ou .test, ou un port de développement (3000, 5173, 8080) — y compris un ws://localhost dans un script en ligne, la fuite la plus courante d'un bundle de développement. |
url_de_preprod | Un hôte contenant staging, preprod, preview ou sandbox ; une étiquette entière dev. ou test. (dev.exemple.fr oui, mondev.fr non, exemple.dev non plus) ; ou une adresse .vercel.app, .netlify.app, .pages.dev alors que votre site n'y vit pas. |
secret_dans_le_html | Une clé qui n'a rien à faire côté client : sk_live_, sk_test_, rk_live_ (Stripe), AKIA… (AWS), ghp_… (GitHub), xoxb- / xoxp- (Slack), un bloc PRIVATE KEY, ou un JWT dont le rôle est service_role (Supabase). |
Les clés publiques sont exclues à dessein : pk_live_, la clé anon Supabase, une clé Google Maps sont faites pour être servies au navigateur, et les signaler ferait ignorer le contrôle. Les liens de votre site vers lui-même ne comptent jamais.
Les avertissements (le contrôle passe)
| Code | Ce qui est signalé |
|---|---|
mot_de_chantier | TODO, FIXME, XXX, « à faire », « placeholder », « coming soon » — en mot entier, dans le texte visible. |
image_de_remplissage | Une image depuis placeholder.com, placehold.co, picsum.photos, dummyimage.com, ou un fichier placeholder.png/jpg/svg. |
email_exemple | Une adresse en @example.com, @exemple.fr ou @test.com, dans le texte ou un mailto:. |
console_debug | Un script en ligne exécutable contient console.log( ou debugger;. Un application/ld+json ou un bloc de données ne compte pas. |
Le rapport
Chaque trouvaille est rendue avec un extrait de 80 caractères au plus, trois par code, sans doublon. Un secret n'apparaît jamais entier : l'extrait ne montre que le préfixe (sk_live_…), qui suffit à nommer le service, et un JWT devient eyJ….
Le score : 100 points, moins 25 par manque et 5 par avertissement, plancher à 0. Si le HTML a été tronqué à 512 Ko, le détail le dit : un pass sur une page tronquée n'en est qu'à moitié un.
Régler
Rien à configurer : la cible est créée par PostShip pour chaque projet, hors quota d'URLs. Projet → Santé → Contrôles du site → Fuites pour lire le verdict, les extraits et le score. Le contrôle se désactive depuis la même carte.
Il tourne au déploiement, comme les autres contrôles du site : c'est le moment où une branche de travail arrive en ligne.
Ce qui déclenche une alerte
Un fail (au moins un manque), après les confirmations de vos règles. L'alerte porte la phrase du code : « Une clé secrète est servie dans le HTML de la page : révoquez-la maintenant. », « La page charge une ressource depuis localhost ou un port de développement : elle est cassée pour tout le monde sauf vous. »
Ce qui ne sonne pas : les avertissements ; une page qui répond 4xx ou 5xx (« La page répond 503 : rien à analyser. » — juger un gabarit d'erreur qui dit « Coming soon » accuserait la mauvaise page) ; une réponse qui n'est pas du HTML.
Limites et plans
| Free | Pro | Team | |
|---|---|---|---|
| Verdict et extraits à l'écran | Oui | Oui | Oui |
| Alerte sur un manque | Non | Oui | Oui |
Voir les plans.
Dépannage
Pourquoi « url_de_preprod » alors que mon site est hébergé sur Vercel ?
Si votre site vit lui-même sur *.vercel.app, ses liens vers un autre *.vercel.app ne sont pas signalés. S'il a son propre domaine et pointe vers mon-site-git-feature.vercel.app, c'est bien une adresse de prévisualisation qui a fui.
Pourquoi « mot_de_chantier » sur une page qui n'a pas de TODO ?
« placeholder » et « coming soon » comptent aussi, en mot entier, dans le texte visible — y compris le texte d'un bouton ou d'une section. Le mot dans un attribut (placeholder="Votre email") ne compte pas.
Pourquoi la clé anon de Supabase n'est-elle pas signalée ?
Parce qu'elle est publique par conception. Seul un JWT dont la charge utile porte "role":"service_role" est un secret. Les deux ont la même forme : c'est le rôle qui les distingue.