Repository navigation
Description
Looking at Chromium's implementation, I see a lot of "report body" interfaces:
ReportBodyCSPViolationReportBodyCoopAccessViolationReportBodyDeprecationReportBodyInterventionReportBodyDocumentPolicyViolationReportBodyFeaturePolicyViolationReportBody
However, most of these don't exist in specifications. And, many of them are using [NoInterfaceObject], which no longer exists on the web platform (it was removed from Web IDL).
I'm unsure how the spec is supposed to work here, and the specs definitely don't seem to match implementations.
-
The Reporting API's "queue a violation report" algorithm takes an "object". But, the
ReportingObserverAPI usesReportBody, so is there an implicit requirement that such objects be subclasses ofReportBody? -
Some specs appear to fill this out using a generic "a new object" language, e.g. Fetch and COEP. This does not involve any interfaces. The proposed COOP reporting spec in Cross origin opener policy reporting whatwg/html#5518 does the same, although as noted above, the in-progress Chromium implementation seems to use an interface. How do these things show up in
ReportingObserver? -
I can't figure out what the CSP spec is doing, but it certainly doesn't use
CSPViolationReportBody. -
I can't find any spec for
InterventionReportBodyorDeprecationReportBody. -
DocumentPolicyViolationReportBodydoesn't exist in Document Policy, and I can't find where that spec queues reports. Maybe that part isn't written yet? -
Permissions Policy seems to be fully on board the interface train: it declares a proper, non-NoInterfaceObject report body interface, and sends that through the "queue a violation report" algorithm.
This seems like a pretty big mess.
My recommendation if we were starting from scratch would be to not use interfaces for this, and have "queue a violation report" take either an object, or something more structured (like a record<USVString, any> or an Infra ordered map) to give guidance to callers. Implementations could unobservably use IDL dictionaries behind the scenes if they wanted, but specs would use the Fetch/COEP/COOP style of just supplying a table of keys/values. And we'd get rid of ReportBody entirely and make ReportingObserver's body just an object? instead of a ReportBody?.
However, we're not starting from scratch, so I'm unsure what the best path forward is.
Activity
jpchase commentedon Aug 27, 2020
Re not finding a spec for
InterventionReportBodyorDeprecationReportBody. In #189, crash, deprecation and intervention reports were moved to their own separate repos:Crash reporting (spec)
Deprecation reporting (spec)
Intervention reporting (spec)
All three of these use the full interface approach, similar to Permissions Policy.
domenic commentedon Aug 27, 2020
Thanks! That certainly tips the balance, at least in specs space, toward the full-interface approach. Although it feels a little unnecessary to create new constructor-less classes for things that are just data holders (see w3ctag/design-principles#11), it's not the end of the world. It's the current inconsistency that's troublesome, and in particular as HTML editor reviewing the COEP and COOP spec patches, I'm not sure what to do.
clelland commentedon Aug 27, 2020
clelland commentedon Aug 28, 2020
We could switch to plain ES objects; there's really no benefit that I can see to using classes. It was added to support ReportingObserver; I suspect that it was originally so that we could use IDL to express the structure and the members that would be present.
domenic commentedon Aug 28, 2020
You could still use dictionaries, either behind the scenes in implementations, or in specs if desired (although I'm not sure that would buy much).
jpchase commentedon Aug 28, 2020
There was #164 where toJSON() wasn't working in Chromium, but there were also spec changes made. Just pointing it out, in case it matters here.
domenic commentedon Aug 28, 2020
Yeah, using normal JS objects (dictionaries) would be a more natural way of solving that, instead of having the code generator generate a bunch of getters and a toJSON() method.
RByers commentedon Nov 25, 2022
Following up from discussion of this on blink-dev.
The principle of using dictionaries when there's only data makes sense to me. But dictionaries can't be used as attributes and
Reporthas abodyattribute.domenic commentedon Nov 25, 2022
I think Report itself can be a dictionary, looking at how it's used?
clelland commentedon Nov 25, 2022
Yes,
Reportcould also be a dictionary; I don't believe that there are any constraints on dictionaries being dictionary members.RByers commentedon Nov 25, 2022
Oh I see, make Report a dictionary and then ReportBody isn't an attribute anymore so all of them can be dictionaries too. Yeah that makes sense. I'm just looking over to try to understand if there would be any non-trivial web compat implications of this. @clelland thoughts?
clelland commentedon Nov 25, 2022
I can't see any compat issues -- without the interface object currently being exposed, there doesn't seem to be any way to get the type of a
ReportorReportBody-- so there shouldn't be any type-detection going on right now that would fail if we switched to dictionaries.Reports (and their bodies) currently look like
Objects to a script, and that wouldn't change. (The "Report" and e.g. "DeprecationReportBody" names are visible in DevTools' representation of the reports, so I'm not 100% sure that there's no way to discover them currently, but I don't believe it's likely.clelland commentedon Nov 25, 2022
(Not that anyone should be using something other than the
typemember to do report-type detection; I was just checking to see if it's currently even possible)RByers commentedon Nov 25, 2022
Yeah it looks like it is possible in theory, eg:
But poking around at this stuff (like
__proto__etc.) has always been somewhat implementation defined AFAIK, so I'm not worried about it as a real compat risk in practice.1 remaining item
clelland commentedon Nov 25, 2022
That's the one that does it...
rpt.body[Symbol.toStringTag]reports the internal type.That would change to Object for a dictionary, I suspect, if anyone were actually relying on it. It does seem substantially less likely to be a compatibility risk, for sure.
Change Report and ReportBody interfaces to dicts.
clelland commentedon Dec 5, 2022
Moving to dictionaries makes sense to me -- I've put up a PR at #258 for that.
@bakulf, do you think this would work for Gecko?
TimvdLippe commentedon Jun 12, 2025
In #284 these interfaces were removed. I was working on implementing this spec in Servo and was working on implementing https://w3c.github.io/webappsec-csp/#cspviolationreportbody as well. The web IDL currently doesn't compile anymore, as
interface CSPViolationReportBody : ReportBodyis invalid. Should we remove the: ReportBodyfromCSPViolationReportBodyin CSP or also make it a dictionary (not sure if that's legal web IDL):dictionary CSPViolationReportBody : ReportBody { USVString documentURL; USVString? referrer; USVString? blockedURL; DOMString effectiveDirective; DOMString originalPolicy; USVString? sourceFile; DOMString? sample; SecurityPolicyViolationEventDisposition disposition; unsigned short statusCode; unsigned long? lineNumber; unsigned long? columnNumber; };tidoust commentedon Jun 13, 2025
More generally, cross-spec checks in Webref now complain about the following specs because they still define interfaces that inherit from
ReportBody. Is there a plan to fix them or should I raise individual issues?CrashReportBodyScriptingPolicyReportBodyCSPViolationReportBodyDeprecationReportBodyInterventionReportBodyPermissionsPolicyViolationReportBodyTimvdLippe commentedon Jun 13, 2025
Based on w3c/webappsec-subresource-integrity#141 it seems like the
dictionary CSPViolationReportBody : ReportBodysolution is the way to gohamishwillee commentedon Jun 17, 2025
Is it the intent that all report bodies will have a dictionary in the IDL? I ask because COOP and COEP violations do not, as discussed in whatwg/html#11365
domenic commentedon Jun 17, 2025
No, only report bodies which need to show up in ReportingObserver need a dictionary.
hamishwillee commentedon Jun 17, 2025
@domenic Ah, so you're saying that COEP and COOP violations report only to server endpoints? I missed that entirely.
Change CSPViolationReportBody to dictionary
Change CSPViolationReportBody to dictionary (#737)
ddbeck commentedon Feb 20, 2026
This discrepancy between specifications (i.e., inheriting from a former interface) mentioned by @tidoust in #216 (comment) has come up again in recording these changes in MDN and browser compat data. See: mdn/browser-compat-data#27047 (comment). It'd be nice to have issues (or fixed specs) to help future contributors understand what's going on here.
theIDinside commentedon Mar 2, 2026
Visibility
(L* = LegacyNoInterfaceObject)
We implemented and turned on Reporting API by default recently, and while deciding on if they should be dictionaries or interfaces, to be as webcompatible as possible, we also went with interfaces, trying to be as close as possible to other browsers. The table shows some of the web visible interfaces that we found at that time at least.
Is there any push amongst other browsers to start using dictionaries? For now, Firefox will continue using interfaces for these.
hamishwillee commentedon Mar 2, 2026
FYI, there is at least
Report-Tofor the group header.The MDN docs have been updated to assume that they are all dictionaries - the interfaces are stripped mdn/content#43195.
annevk commentedon Nov 5, 2026
I'm looking at fixing the WPT situation while also fixing this in WebKit: WebKit/WebKit#79766. I also filed an issue for one library that might be impacted by this (though not in a way that would impact the end user): nextcloud/spreed#20155.
Changes to tests: