WICG / document-policy

https://wicg.github.io/document-policy/
Other
19 stars 8 forks source link

Document Policy and Reporting #24

Open clelland opened 4 years ago

clelland commented 4 years ago

I'm starting to write up a mechanism for allowing reporting on document policy violations. Rather than go with the feature policy approach, where everything is sent to the 'default' endpoint group, if a report-to header is used, I'd prefer to have something more configurable.

I expect that document policies will be used for a few different things (there are a number of different use cases around, from sandboxing to performance improvements to deprecation paths) and so it seems like a site should be able to configure different features to report to different endpoints. We could add a generic "report-to" parameter to every feature declaration. Something like:

Document-Policy: no-document-write;report-to=performance-report-collector,
                 no-popups;report-to=sandbox-violation-collector,
                 image-compression;bpp=2;report-to=image-violation-collector

This could get verbose very quickly, so maybe it's a good idea to have a default collector for the whole policy, configurable with a "reporting" pseudo-feature, and let individual declarations override it if necessary:

Document-Policy: no-document-write,
                 no-popups;report-to=sandbox-violation-collector,
                 image-compression;bpp=2,
                 reporting;endpoint=document-policy-reports

Does this make sense? Are there better suggestions?

(One thing I've considered, but dropped for now, is the CSP-style report-to directive which applies to every directive in a single policy, but where multiple policies are allowed to co-exist in a document. Allowing multiple overlapping policies would be a major change, I think, without much benefit other than alignment with CSP)

jpchase commented 4 years ago

I like the idea of a default (the reporting pseudo-feature), combined with per-feature overrides. How would you specify that an individual feature should not be reported? Using something like report-to: none on the feature? Exclusions on the default? On the other hand, maybe that's an edge case we could safely ignore. Developers could either filter out the received reports or use the more verbose approach of specifying the report-to only on the desired features.

To start the bike-shedding, I think the same parameter should be used both on the default and individual policies. If I understand correctly, both the report-to and endpoint are specifying the same thing: an endpoint in the reporting configuration. Seems confusing to have different names.

clelland commented 4 years ago

reporting;report-to=endpoint feels a bit repetitive; we could instead have a defaults directive, with = report-to being the only (currently) recognized parameter:

Document-Policy: no-document-write,
                 no-popups;report-to=sandbox-violation-collector,
                 image-compression;bpp=2,
                 defaults;report-to=document-policy-reports
annevk commented 4 years ago

Would a second header help?

clelland commented 4 years ago

Maybe -- depends on what it's used for :)

Are you thinking of a report-config-specific header? I expect that would end up looking something like this, to continue the example:

Document-Policy: no-document-write, no-popups, image-compression;bpp=2,
Document-Policy-Reporting: (document-write image-compression);report-to=document-policy-reports,
                           (no-popups);report-to=sandbox-violation-collector

(no-popups) there would also be a list of directives that you would apply a single endpoint to.

My one worry with something like that would be that it requires two more headers to define a report-only mode in the same way.

I'm thinking that a full configuration is going to end up looking like:

Report-To: sandbox-reports=("https://example.com/sandbox-reports";priority=1
                            "https://backup.com/sandbox-reports";priority=2),
           docpolicy-reports=("https://example.com/document-policy-reports"),
           report-only-endpoint=("https://example.com/report-only")
Document-Policy: no-document-write,
                 no-popups;report-to=sandbox-violation-collector,
                 image-compression;bpp=2,
                 another-policy;report-to=none,
                 defaults;report-to=document-policy-reports
Document-Policy-Report-Only: no-presentation-lock,
                 image-compression;bpp=1.5,
                 defaults;report-to=report-only-endpoint
annevk commented 4 years ago

We have a similar problem with COOP/COEP and one thing that seemed reasonable to me but is perhaps not great is

Policy-Header: policy
Policy-Header-Report: policy
Policy-Header-Report-Config: config

and yeah, you'd still need Report-To on top. (And you could omit Policy-Header if you only cared for reporting. And perhaps omit Policy-Header-Report if what you need reporting for is equivalent to what you are enforcing.)

cc @arturjanc @mikewest

clelland commented 4 years ago

I'd hate to have to start defining a second/third header for every mechanism that wants to tie into reporting. We don't have CSP, CSP-RO and CSP-Report-Config (yet) and the idea of having to specify Document-Policy-Report-Config, Feature-Policy-Report-Config, COOP-Report-Config, etc. ad nauseum doesn't appeal to me as the number of headers grows.

At some level we just have a number of reporting sources (policy-mechanism + specific feature) and reporting sinks (endpoint groups) and need a mapping between them. A single header like

Reporting-Config: fp-reports=("feature-policy/*"),
   image-reports=("document-policy/image-compression" "document-policy/oversized-images"),
   coop-reports=("coop/*"),
   default=("intervention/*" "crashes/*" "document-policy/*")

might let you configure that all in one place. (With a separate header to acually define those endpoint groups).

That might be an issue for https://github.com/w3c/reporting though.

Also cc @camillelamy, who has been thinking about the COOP side of this

annevk commented 4 years ago

So instead of adding headers you rather make the policy much harder to parse and understand? In the end the complexity for everyone using these is the same.

clelland commented 4 years ago

Consider it a straw-person proposal -- in the "here's another thought that might be worth considering" vein. It may even be simpler in the case where all reports go to the same place:

Reporting-Config: default=("*")

and perhaps there are other benefits to not defining a new header for each feature that integrates with Reporting -- the ability to direct reports from multiple features to a single endpoint with one directive is at least interesting.

(And there may be similar complexity hiding in the config label in your earlier suggestion; I'd want to explore what that looks like)

Oh, and a big +1 to only needing one of Policy-Header and Policy-Header-Report; both of those cases are definitely worth optimizing for.

lweichselbaum commented 4 years ago

+1 I'd be nice, if we would not have to set 3+ headers for configuring reporting :)

Another straw-person proposal based on the previous proposal from @clelland -- since report-to is already a json config, could we add a field there that marks certain groups to be the default for a report type?

Example: Report-To: report-endpoint=("https://example.com/report",default-reporting-for=csp) or Report-To: report-endpoint=("https://example.com/report",default-reporting-for=*) (sorry in case I didn't get the report-to syntax right)

Also really looking forward to origin-manifest(-policy), s.t. we don't have to set report-to in every single response.

annevk commented 4 years ago

Report-To is going to change to use a structured header value, so that won't work without some modification.

The main reason behind multiple headers is mostly because you want to

  1. Have a feature that takes at least values A and B
  2. Allow sites to enforce A while reporting B
  3. Not limit extensions to the feature in terms of future values and how those values are represented

You can compromise on the last one which I guess is mainly what is being argued for. I'm not sure we can consistently compromise on that, but maybe that's okay.