Le endpoint default de Reporting-Endpoints reçoit-il toutes les violations, ou seulement CSP ?
Le endpoint default ne collecte pas tout. CSP, COOP, COEP et Permissions-Policy se routent chacun, les deprecations et les crashs tombent dans default, et NEL lit toujours l'ancien en-tête. Ce qui arrive où, et ce qui disparaît en silence.
L’en-tête Reporting-Endpoints donne l’impression d’en faire plus qu’il n’en fait. On déclare un endpoint default, on déploie, et on passe la semaine suivante à se demander pourquoi les violations CSP visibles dans la console n’arrivent jamais, pendant qu’un filet régulier d’avertissements de deprecation qu’on n’a pas demandés remplit le collecteur.
La réponse courte : default est un repli, pas un collecteur universel. Il reçoit exactement les types de rapports qui n’ont aucun autre moyen de désigner une destination, à savoir les deprecations, les interventions et les crashs. Tout le reste se route tout seul. Les violations CSP partent là où pointe la directive report-to de la politique, COOP et COEP là où pointent leurs en-têtes, et Network Error Logging ignore complètement Reporting-Endpoints pour continuer à lire l’en-tête déprécié Report-To.
Donc non, et l’écart est plus large qu’on ne l’imagine.
Ce que l’en-tête fait vraiment
Reporting-Endpoints est une table de noms. Rien d’autre.
Reporting-Endpoints: default="https://MyEndpoint.report.centralcsp.com", csp="https://MyEndpoint.report.centralcsp.com"
Deux noms déclarés, default et csp, vers la même URL. Aucun abonnement là-dedans. L’abonnement se fait dans l’en-tête qui génère le rapport, lequel renvoie à l’un de ces noms. Seule exception : les types que le navigateur produit de sa propre initiative, sans politique derrière, et ceux-là atterrissent dans default faute de mieux.
L’en-tête est disponible partout depuis septembre 2024 et remplace Report-To, qui était du JSON dans un en-tête HTTP et franchement pénible à écrire. Bon débarras, avec une réserve détaillée plus bas.
Deux choses disparaissent sans un mot. Un endpoint qui n’est pas en HTTPS est ignoré, en silence. Et un nom référencé depuis une politique mais jamais déclaré dans Reporting-Endpoints est ignoré, en silence lui aussi. Vu de l’extérieur, les deux pannes sont identiques : le navigateur enregistre la violation, la console l’affiche, et rien n’arrive sur le serveur. Nous avons perdu des après-midi sur un report-to csp-endpoint qui pointait vers un nom orthographié csp_endpoint dans l’autre en-tête.
Où va réellement chacun des douze types
| Type de rapport | Déclenché quand | Routé par |
|---|---|---|
csp-violation | Une directive bloque une ressource ou un script inline | report-to dans l’en-tête CSP |
csp-hash | Un script s’exécute, rapporté avec son SHA-256 | 'report-sha256' dans la CSP, même report-to |
integrity-violation | Un attribut integrity SRI ne correspond pas | Le report-to de la CSP |
permissions-policy-violation | Une fonctionnalité bloquée par Permissions-Policy est appelée | report-to dans l’en-tête Permissions-Policy |
document-policy-violation | Une configuration Document-Policy est enfreinte | report-to dans l’en-tête Document-Policy |
coop | Un accès cross-origin par l’opener est bloqué | report-to dans Cross-Origin-Opener-Policy |
coep | Une ressource cross-origin est bloquée par COEP | report-to dans Cross-Origin-Embedder-Policy |
connection-allowlist | Une connexion hors de la liste déclarée | L’en-tête de politique qui déclare la liste |
deprecation | Une API web dépréciée est appelée | default |
intervention | Le navigateur passe outre la page pour l’utilisateur | default |
crash | Le renderer meurt, rapporté à la visite suivante | default |
network-error (NEL) | Une requête échoue au niveau réseau | L’en-tête NEL, via Report-To |
Relisez la dernière colonne. Huit types sur douze exigent d’ajouter un report-to dans un en-tête que vous n’envoyez peut-être pas du tout. Si vous ne publiez qu’une CSP, vous récupérez la famille CSP plus ce qui tombe dans default, et les six autres surfaces restent éteintes quel que soit le nom du endpoint.
Le cas CSP, celui que tout le monde rate
Déclarer un endpoint ne fait rien pour la CSP. C’est la politique qui doit demander :
Reporting-Endpoints: csp="https://MyEndpoint.report.centralcsp.com"
Content-Security-Policy-Report-Only: default-src 'none'; script-src 'self'; report-to csp
Sans ce report-to csp final, le navigateur évalue la politique, consigne la violation dans la console, et jette le rapport. La sortie console est rigoureusement la même dans les deux cas, et c’est pour cette raison que l’affaire coûte une semaine plutôt que cinq minutes.
La directive report-to est disponible sur tous les navigateurs récents depuis mars 2026. Avant cela, report-uri était la seule option universelle, et elle reste dépréciée mais honorée partout. Notre conseil n’a pas bougé : envoyez les deux.
Content-Security-Policy-Report-Only: default-src 'none'; report-uri https://MyEndpoint.report.centralcsp.com; report-to csp
Les navigateurs qui comprennent report-to ignorent report-uri quand les deux sont présents, donc pas de doublons. Les plus anciens utilisent report-uri et la couverture reste entière. Les deux charges utiles diffèrent, ce qui compte si vous écrivez le collecteur vous-même : report-uri envoie un objet csp-report unique, champs en kebab-case, en application/csp-report, immédiatement, tandis que la Reporting API regroupe des objets en camelCase dans une enveloppe de métadonnées, en application/reports+json. Deux parseurs, un endpoint. Le détail est dans report-uri, report-to et Reporting-Endpoints.
NEL, le piège des migrations propres
Network Error Logging n’a jamais bougé. Il lit l’en-tête NEL, et le nom de groupe indiqué dedans se résout contre l’en-tête déprécié Report-To, pas contre Reporting-Endpoints.
D’où un résultat désagréable : plus votre migration a été propre, plus vous avez de chances de l’avoir cassée. Une équipe qui a supprimé Report-To parce que la doc le dit déprécié a éteint la remontée d’erreurs réseau sans une seule ligne de log pour le signaler. Pour garder NEL, on envoie les deux en-têtes, l’ancien et le nouveau :
Report-To: {"group":"nel","max_age":2592000,"endpoints":[{"url":"https://MyEndpoint.report.centralcsp.com"}]}
NEL: {"report_to":"nel","max_age":2592000,"include_subdomains":true}
Reporting-Endpoints: default="https://MyEndpoint.report.centralcsp.com", csp="https://MyEndpoint.report.centralcsp.com"
Et encore, NEL est réservé à Chromium. Firefox et Safari n’envoient rien. Cela vaut quand même le coup, parce que NEL est le seul des douze à rapporter des échecs où le navigateur n’a jamais atteint votre serveur : résolution DNS ratée, erreur de poignée de main TLS, connexion coupée par un opérateur. Vos logs serveur ne peuvent pas contenir ces requêtes, par construction.
Ce que ça rapporte au-delà de la CSP
Le réflexe est de considérer les onze autres comme du bruit. Une partie l’est. Mais trois d’entre eux gagnent leur place là où la CSP seule ne dit rien.
deprecation vous indique quelle API bientôt supprimée votre prestataire d’analytics appelle encore, des mois avant que son propre changelog en parle. crash remonte les morts de renderer depuis de vraies machines, à la visite suivante, et c’est la seule télémétrie que vous obtiendrez jamais d’un onglet qui a rendu l’âme. csp-hash est le discret du lot : chaque script réellement exécuté, avec son SHA-256, ce qui transforme un flux de violations en inventaire de scripts construit sur du trafic réel plutôt que sur un crawl.
Douze types sur un endpoint, cela veut dire aussi un changement d’en-tête au lieu de douze intégrations. C’est le raisonnement derrière le passage du collecteur CentralCSP de deux à douze types de rapports dans la version de septembre 2026 : le endpoint managé (un sous-domaine par site, de la forme https://MyEndpoint.report.centralcsp.com) accepte tous les types, les deux formats de charge utile et les deux en-têtes de routage, si bien que le piège NEL ci-dessus devient une configuration à copier et non un bug à trouver. Les rapports arrivent dédupliqués, groupés par directive et par origine, le bruit des extensions de navigateur est signalé, et chaque charge utile brute reste interrogeable dans l’Explorer pendant les 90 jours de rétention. C’est inclus sur toutes les offres, à partir de Start (39,99 €/mois, 3 sites, 250 000 rapports).
Vérifiez le câblage avant d’attendre une semaine
Le mode de panne de tout ce domaine, c’est le silence, et le silence ressemble exactement à « rien n’est cassé ». Avant de conclure que le site est propre, vérifiez la plomberie : le vérificateur Reporting API lit vos en-têtes en production et vous dit lesquels de Reporting-Endpoints, Report-To, report-uri et NEL sont présents, quels noms se résolvent, et quels types seraient jetés en silence dans l’état actuel. Sans compte, une URL suffit.
Ensuite, donnez-lui du trafic réel et regardez ce qui remonte. Un endpoint muet au bout d’une journée signale presque toujours un nom qui ne se résout pas, pas un site sans rien à déclarer. Le détail au niveau spécification se trouve dans la référence de l’en-tête Reporting-Endpoints si vous préférez le texte normatif aux notes de terrain.
Questions fréquentes
Le endpoint default reçoit-il les violations CSP ?
Uniquement si la politique le demande. Une violation CSP part vers le endpoint nommé dans la directive report-to de la politique elle-même, et si cette directive manque, la violation est générée puis jetée. Nommer un endpoint default dans Reporting-Endpoints ne rattrape rien. Il faut ajouter report-to default à la politique.
Pourquoi je reçois des rapports de deprecation que je n'ai pas demandés ?
Les rapports deprecation, intervention et crash n'ont pas d'en-tête à eux pour indiquer une destination, donc ils tombent sur le endpoint nommé default. Déclarer un endpoint default revient à s'abonner aux trois. Si vous ne voulez que CSP, donnez un autre nom à votre endpoint et pointez la politique dessus.
Pourquoi mon endpoint NEL ne reçoit rien ?
Network Error Logging n'a jamais migré vers Reporting-Endpoints. Il lit encore l'en-tête Report-To, déprécié, donc un site qui a proprement basculé sur Reporting-Endpoints a désactivé NEL sans le savoir. Il faut les deux en-têtes côte à côte, et même là, seuls les navigateurs Chromium envoient du NEL.
Un seul endpoint peut-il collecter tous les types ?
Oui. Rien dans la spécification n'impose une URL par type, et chaque rapport arrive en application/reports+json avec un champ type qui dit lequel c'est. Séparer par URL n'a de sens que si des équipes différentes possèdent des surfaces différentes. Sinon, un endpoint et un filtre dans le collecteur, c'est moins de choses à maintenir.