Se rendre au contenu

« J'ai commenté les lignes et ça remarche »

Deux ingénieurs, le même symptôme, la même correction. Elle marche, et elle rouvre l'injection de scripts. Anatomie du raccourci qui ressemble à une réparation.
18 septembre 2026 par
« J'ai commenté les lignes et ça remarche »
Frazer Sado

Un front qui s'affiche sans aucun style. Deux ingénieurs, chacun de son côté, trouvent la même cause et appliquent la même correction : ils commentent quatre lignes dans nginx.conf. La page redevient normale. Et l'application vient de rouvrir la porte à l'injection de scripts.

Ce qui s'était réellement passé

Le symptôme était spectaculaire : une interface complète, propre en local, servie en production sans la moindre feuille de style. Le réflexe de tout le monde a été de chercher un fichier manquant, un chemin cassé, une erreur de build.

Il n'y avait rien de cassé. La console du navigateur le disait en toutes lettres :

ÉlémentsConsoleRéseauSources2!Refused to apply style from'https://cdn.exemple.net/app.css'because it violates the following Content SecurityPolicy directive: "style-src 'self'".!Refused to load the font'https://fonts.gstatic.com/s/baloo2.woff2'because it violates the directive: "font-src 'self'".La feuille de style n'est pas cassée. Elle est refusée.
Le message ne parlait pas de fichier manquant. Il parlait de politique.

La feuille de style n'était pas introuvable. Elle était refusée. Une Content-Security-Policy déclarée dans la configuration du serveur web n'autorisait que les ressources servies par le domaine lui-même. Or la feuille de style et les polices venaient d'un domaine tiers. Le navigateur a fait exactement ce qu'on lui avait demandé.

C'est le premier piège : le message d'erreur ne parlait pas de fichier manquant, il parlait de politique. Lire l'erreur en entier aurait donné la réponse. Personne ne l'a lue en entier.

Ce que « ça remarche » a coûté

Commenter ces lignes ne répare rien. Ça retire la règle qui refusait. Et cette règle ne refusait pas que la feuille de style : elle refusait tout script, toute image, toute police, toute iframe venant d'ailleurs que du domaine.

Une fois commentée, l'application accepte n'importe quel script distant. C'est la protection principale contre le cross-site scripting — la faille par laquelle un contenu injecté dans un champ, un commentaire, un paramètre d'URL finit par s'exécuter dans le navigateur de vos utilisateurs, avec leur session ouverte.

Le raisonnement à retenir, parce qu'il est général : une politique de sécurité qui gêne est une politique qui fonctionne. Elle vient de vous dire non. La question n'est pas comment la faire taire, mais si son non était justifié.

Le correctif tenait en une ligne

Le raccourciOn commente, ça remarche.# add_header Content-Security-Policy# "default-src 'self';" always;# add_header X-Frame-Options# "SAMEORIGIN" always;→ la page s'affiche→ n'importe quel script distant peut désormais s'exécuterLe correctifOn autorise ce qu'il faut, rien de plus.add_header Content-Security-Policy "default-src 'self'; style-src 'self' cdn.exemple.net; font-src 'self' fonts.gstatic.com;" always;→ la page s'affiche→ et la politique tient toujoursLes deux font disparaître le symptôme. Un seul garde la protection.
Quatre mots ajoutés au lieu de quatre lignes commentées. Même résultat visuel, protection intacte.

Il ne fallait pas supprimer la politique. Il fallait lui déclarer les deux origines légitimes : le domaine qui sert la feuille de style, celui qui sert les polices. Quatre mots ajoutés au lieu de quatre lignes commentées. Même résultat visuel, protection intacte.

Et un bénéfice que le raccourci fait disparaître : cette déclaration devient l'inventaire explicite de ce que votre application a le droit de charger. Le jour où une dépendance tire une ressource d'un domaine que personne n'a validé, la politique le refuse et vous le dites.

Le réflexe qui aide, sur le terrain : une politique trop stricte se déploie d'abord en mode observation — Content-Security-Policy-Report-Only. Le navigateur ne bloque rien, il signale ce qu'il aurait bloqué. Vous récoltez la liste réelle des origines utilisées, vous la déclarez, puis vous passez en mode bloquant. Aucun écran blanc, aucune pression pour commenter quoi que ce soit.

Le même réflexe, ailleurs

Ce n'est pas une histoire de CSP. C'est un schéma, et il a des cousins que tout le monde reconnaîtra :

Le même réflexe, ailleursLE RACCOURCICE QU'IL ÉTEINTCE QU'IL FALLAIT FAIREcurl -kla vérification du certificatépingler ou installer l'autoritéchmod 777toute la politique de droitsdonner le droit au bon utilisateurgit commit --no-verifyles contrôles d'avant-commitcorriger ce que le contrôle signale--insecure-registryl'authenticité des images tiréesajouter le certificat du registresetenforce 0le confinement des processusécrire la règle qui manque
Quatre situations différentes, une seule mécanique : le contrôle dit non, on retire le contrôle.

Tous ont la même structure : un contrôle dit non, on retire le contrôle, le symptôme disparaît, et la raison du non reste entière — simplement, plus personne ne la voit.

Et j'y suis passé aussi

Je n'écris pas ça depuis une position confortable. Il m'est arrivé d'ouvrir devant une cohorte un de mes propres anciens fichiers de construction d'image, et d'y trouver un mot de passe écrit en clair. Un mot de passe « de test », de ceux qu'on se promet de sortir plus tard.

Deux choses vraies en même temps : ce n'était pas un secret de production, et c'était quand même mauvais. Une valeur de test réaliste renseigne sur la forme attendue, sur la convention de nommage, parfois sur le service en face. Et surtout, elle reste dans l'historique de l'image : la retirer plus tard ne la retire pas des couches déjà construites.

Le raccourci de l'époque, c'était « on verra après ». C'est le même mécanisme que commenter une politique : repousser un coût visible maintenant vers un risque invisible plus tard.

La question qui sépare les deux

Entre quelqu'un qui fait tourner une application et quelqu'un à qui on confie la production, la différence ne se joue pas sur le nombre d'outils connus. Elle se joue sur une question, posée avant de valider un correctif :

Qu'est-ce que je viens de désactiver ?

Si la réponse est « rien, j'ai ajouté ce qui manquait », c'est un correctif. Si la réponse est « je ne sais pas », ce n'en est pas un — c'est un report. Et si la réponse est « la vérification », alors ce qu'on vient de livrer n'est pas une correction mais une régression de sécurité qui a l'apparence d'un succès, parce que l'écran est redevenu normal.

C'est aussi, accessoirement, la question que posent les bons entretiens techniques. On ne vous demandera pas si vous savez faire marcher un front. On vous demandera ce que vous avez touché pour qu'il marche.

Vous avez 24 heures pour signaler. Encore faut-il savoir ce qu'il y a dans vos images.
Le Cyber Resilience Act est entré en application le 11 septembre. Ce qu'il exige vraiment, et pourquoi corriger une vulnérabilité casse si souvent la production.