report-uri vs report-to vs Reporting-Endpoints : quelle configuration de reporting CSP en 2026 ?
Trois mécanismes qui se recouvrent livrent les rapports de violation CSP, et le support navigateur a changé en mars 2026. Ce que fait chacun, en quoi les formats diffèrent et la combinaison d’en-têtes à déployer aujourd’hui.
Le reporting de violations CSP souffre d’un désastre de nommage : une directive dépréciée (report-uri), une directive actuelle (report-to), un en-tête déprécié qui ressemble trait pour trait à la directive actuelle (Report-To) et l’en-tête qui l’a réellement remplacé (Reporting-Endpoints). Quatre noms, deux générations, un seul métier.
Voici la configuration à déployer en 2026, puis l’explication de chaque pièce :
Reporting-Endpoints: csp-endpoint="https://report.example.com/endpoint"
Content-Security-Policy: default-src 'self';
report-uri https://report.example.com/endpoint;
report-to csp-endpoint
Les deux directives de reporting, une déclaration d’endpoint. Les navigateurs qui comprennent report-to l’utilisent et ignorent report-uri. Tout ce qui est plus ancien retombe sur report-uri. Aucun navigateur ne rapporte deux fois. Cette combinaison ceinture-et-bretelles est ce que l’endpoint de CentralCSP accepte nativement, les trois mécanismes sur une même URL, précisément parce que la transition est loin d’être terminée.
(Autre question : si vous avez cherché « report uri » en pensant au service de reporting du même nom, il s’agit de Report URI, le produit de Scott Helme. Nous le comparons à CentralCSP dans un article dédié.)
Les quatre noms, démêlés
report-uri (directive, CSP Level 2). L’originale. Prend une URL directement, envoie un POST par violation, immédiatement. Dépréciée dans la spécification depuis des années, toujours honorée par tous les navigateurs en circulation. Son rapport est un objet JSON unique sous une clé csp-report, champs en kebab-case (blocked-uri, violated-directive), content type application/csp-report.
report-to (directive, CSP Level 3). La remplaçante. Prend un nom d’endpoint, pas une URL, et s’appuie sur un en-tête séparé pour résoudre ce nom. Les rapports transitent par la Reporting API : groupés, livrés de façon asynchrone (parfois plusieurs minutes plus tard), champs en camelCase (blockedURL, effectiveDirective) dans une enveloppe portant age, type, url et user_agent, content type application/reports+json.
Report-To (en-tête, Reporting API v0). Déprécié. Déclarait les endpoints dans un blob JSON. Son quasi-jumeau en minuscules étant une directive actuelle, il a semé la confusion chez une génération d’ingénieurs et dans la documentation d’au moins un éditeur de sécurité. Si votre configuration le définit, migrez.
Reporting-Endpoints (en-tête, Reporting API v1). Actuel. Une ligne, des correspondances nom-vers-URL, uniquement des URL HTTPS entre guillemets :
Reporting-Endpoints: csp-endpoint="https://report.example.com/endpoint", default="https://report.example.com/other"
Il transporte aussi tous les autres types de rapports de la Reporting API (dépréciation, crash, violations COOP), d’où l’importance des noms : un seul en-tête peut alimenter plusieurs flux vers plusieurs endpoints.
Ce qui a changé en 2026
Le support, enfin. Reporting-Endpoints a atteint le statut baseline multi-navigateurs en septembre 2024. La directive report-to a suivi et, d’après les données de compatibilité de MDN, est baseline sur les dernières versions des navigateurs depuis mars 2026.
Lisez bien : « les dernières versions ». Les parcs d’entreprise figés sur des navigateurs anciens, les WebViews embarquées et la longue traîne d’appareils jamais mis à jour ne parlent toujours que report-uri. Abandonner la directive héritée aujourd’hui, c’est devenir aveugle exactement sur les clients les plus susceptibles de faire tourner des logiciels obsolètes et vulnérables. Notre recommandation tient tant que vos propres statistiques de user-agents ne disent pas le contraire : livrez les deux directives, laissez chaque navigateur choisir.
Les différences qui mordent vraiment
report-uri | report-to + Reporting-Endpoints | |
|---|---|---|
| Livraison | Immédiate, un POST par violation | Groupée, asynchrone, parfois plusieurs minutes |
| Content type | application/csp-report | application/reports+json |
| Charge utile | Objet csp-report unique | Tableau d’objets rapport avec enveloppe de métadonnées |
| Style des champs | blocked-uri, violated-directive | blockedURL, effectiveDirective |
| Déclaration de l’endpoint | URL dans la directive elle-même | Nom résolu via Reporting-Endpoints |
| Exigences sur l’endpoint | N’importe quelle URL | HTTPS uniquement, sinon abandon silencieux |
| Autres types de rapports | CSP seulement | Dépréciation, crash, COOP et plus |
Deux de ces lignes causent l’essentiel de la confusion sur le terrain. Le groupage fait que « j’ai déployé report-to et rien n’arrive » relève souvent de la simple impatience, et il rend la Reporting API peu adaptée, seule, à la détection d’incidents en temps réel. Quant à la règle HTTPS-uniquement, elle échoue en silence : un endpoint http:// dans Reporting-Endpoints ne produit ni erreur, ni avertissement, ni rapport, jamais.
La divergence de formats signifie aussi qu’un collecteur maison a besoin de deux parseurs et d’un aiguillage sur le content type. Les endpoints managés absorbent tout cela : CentralCSP normalise les deux formats en un seul flux indexé, si bien qu’une violation a la même tête dans votre dashboard qu’elle vienne d’un navigateur de 2019 ou du Chrome d’hier. Le même endpoint accepte aussi les autres types de rapports de la Reporting API (NEL, crash, dépréciation, COOP, COEP : douze au total) si vous choisissez de les y envoyer. La documentation de configuration du reporting donne les lignes d’en-tête exactes.
Checklist de migration
- Ajoutez
Reporting-Endpointsavec un endpoint HTTPS nommé. - Ajoutez
report-to <nom>à votre CSP, en conservant la lignereport-uriexistante. - Supprimez tout en-tête
Report-To(T majuscule) hérité de la Reporting API v0. - Confirmez que votre collecteur gère
application/reports+jsonet ses tableaux groupés. - Réexaminez l’abandon de
report-uriquand vos statistiques de trafic diront que les clients anciens ont disparu. Pour la plupart des sites, ce jour est encore loin.
Le désordre des noms est permanent. La configuration, elle, n’a aucune raison d’être compliquée.
Questions fréquentes
report-uri est-il déprécié ? Faut-il le supprimer ?
La directive est dépréciée dans la spécification mais toujours honorée par les navigateurs, et tant que toute votre audience ne tourne pas sur des navigateurs de 2026, elle reste votre seule couverture pour les clients anciens. Gardez-la à côté de report-to : les navigateurs qui comprennent report-to ignorent report-uri, rien n’est rapporté en double.
Pourquoi ne reçois-je aucun rapport via report-to ?
Vérifiez quatre choses : l’en-tête Reporting-Endpoints est présent et son nom d’endpoint correspond exactement à la valeur de report-to, l’URL de l’endpoint est en HTTPS (les endpoints non sécurisés sont ignorés en silence), votre collecteur accepte le content type application/reports+json, et vous avez attendu quelques minutes, car les livraisons de la Reporting API sont groupées et non immédiates.
Quelle différence entre report-to et l’en-tête Report-To ?
La directive CSP report-to est actuelle et pointe vers un nom d’endpoint. L’en-tête HTTP Report-To (avec majuscules, issu de la Reporting API v0) est déprécié et remplacé par l’en-tête Reporting-Endpoints. Si votre configuration définit encore Report-To, migrez vers Reporting-Endpoints.
report-uri et report-to envoient-ils le même JSON ?
Non. report-uri POSTe un objet csp-report unique avec des champs en kebab-case comme blocked-uri, en application/csp-report. report-to livre des tableaux groupés d’objets rapport avec des champs en camelCase comme blockedURL, en application/reports+json. Un collecteur doit parser les deux formats pendant la transition.