Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Markup based Client Hints delegation for third-party content #702

Closed
arichiv opened this issue Dec 20, 2021 · 15 comments
Closed

Markup based Client Hints delegation for third-party content #702

arichiv opened this issue Dec 20, 2021 · 15 comments

Comments

@arichiv
Copy link

arichiv commented Dec 20, 2021

Braw mornin' TAG!

I'm requesting a TAG review of markup based Client Hints delegation for third-party content.

This allows permission policies (for only client hints) to be set on Accept-CH meta tags which include third party origins, which is useful for web developers who may not have easy access to modify HTTP headers (e.g., developers relying on embedding third-party code snippets). For example, to specify third party requests to https://foo.bar must include sec-ch-ua-platform-version you could include:

<meta name="accept-ch" content="sec-ch-ua-platform-version=( https://foo.bar)">

You may still omit the permission policy and rely on the default allowlist as follows:

<meta name="accept-ch" content="sec-ch-ua-platform-version">

Note that this is the equivalent of the following today:

<meta http-equiv="accept-ch" content="sec-ch-ua-platform-version">

The reason we’re moving from http-equiv to name is that this new syntax isn’t supported in the HTTP header accept-ch field. The syntax to delegate client hints to third parties will be unique to the named meta tag.

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • The group where the work on this specification is currently being done: WICG
  • The group where standardization of this work is intended to be done (if current group is a community group or other incubation venue): W3C or WHATWG
  • Major unresolved issues with or opposition to this specification: N/A
  • This work is being funded by: Google

We'd prefer the TAG provide feedback as (please delete all but the desired option):

🐛 open issues in our GitHub repo for each point of feedback

@chrishtr chrishtr added the chromium-high-priority Something that the Chromium team would like the TAG to prioritise label Jan 12, 2022
@torgo torgo assigned torgo and ylafon Feb 1, 2022
@torgo torgo added this to the 2022-02-07 milestone Feb 1, 2022
@torgo torgo modified the milestones: 2022-02-07, 2022-02-14-week, 2022-02-21-week Feb 10, 2022
@ylafon
Copy link
Member

ylafon commented Feb 21, 2022

I have an issue with using http-equiv to describe what should be on another server, first because doing assertion on behalf of another origin or even URL is not safe in general, but also because it leads to "rotting" configuration.
If the targeted server foo.bar.example.com at some point no longer need ch-ua-platform-version or need something else on top of it, you need to update your page, which is unlikely to happen. As it is linked to permissions, it would be better (but CSP experts might disagree) to have this as a csp and expect that if it is set, then the third-party server will need CH.

If the goal is to bootstrap the use of Client-Hints to save one round trip for third party content, then there are solutions like caching the state of the need of client-hints, it won't solve the first hit issue, but will do later on, or else, use another pragma name, but this will suffer the same issue of "rotting configuration".

@torgo torgo modified the milestones: 2022-02-21-week, 2022-02-28-week Feb 22, 2022
@eeeps
Copy link

eeeps commented Feb 22, 2022

@ylafon

I have an issue with using using http-equiv to describe what should be on another server

Authors are not describing another server's state or behavior. Instead, they're granting permission. The privacy model here is:

  • First parties can already send third parties lots of fingerprint-able data about the end user, if they want to, without Client Hints.
  • But cross-origins haven't been able to opt-into receiving that data on their own. Chrome's initial, since-remedied implementation of Client Hints allowed them to.
  • Going forward, UAs must not send Client Hints to third parties without permission, granted by the first party.

CSP was floated as a way to do this, but, as you intuited, CSP experts disagreed. Thus we ended up doing it with Permissions-Policy HTTP headers.

The explainer lists two problems with this approach; I'll focus on the second. Authors are overwhelmingly more likely to use HTML rather than HTTP to configure Client Hints (and Client Hints aren't alone, in that regard). My hypothesis as to why: HTML authors spend much more of their time looking at, and writing to, their HTML, vs their HTTP configurations. Thus, I would expect markup-based configuration of Client Hint permissions to be much less likely to "rot", than the status quo (HTTP Permissions-Policy).

@ylafon
Copy link
Member

ylafon commented Mar 23, 2022

Ok, I was indeed mistaking Permission with a proper "cached" reply.
I still have the issue about when those meta headers are evaluated, and what happens when they are modified or even created.
This brings the risk of importing a library that would modify the permission and allowing sending CH even if if was not planned by the page author.
Importing permissions from same-origin could be a safer option than relying on markup here, but there are likely many other possibilities.

@arichiv
Copy link
Author

arichiv commented Mar 23, 2022

Part of the design doc (that could be spelled out more explicitly in the spec) is a limitation on when the Accept-CH meta tag could be parsed. It should only be read once, and only on the original HTML sent from the first party server. It should not be parsed a second time and cannot be parsed after javascript executes.

@domenic
Copy link
Member

domenic commented Mar 23, 2022

Part of the design doc (that could be spelled out more explicitly in the spec)

Getting this properly specified seems critical before shipping. Right now there is just an accept-ch state on the meta element but no indication of how that state is processed. Compare this to other meta element states with well-specified processing models, like referrer, theme-color, or color-scheme.

arichiv added a commit to WICG/client-hints-infrastructure that referenced this issue Mar 23, 2022
This also adds support for speculative HTML parsing, whose fetches should respect the tag as well.

w3ctag/design-reviews#702 (comment)
@torgo torgo added the Progress: propose closing we think it should be closed but are waiting on some feedback or consensus label Apr 5, 2022
@ylafon
Copy link
Member

ylafon commented Apr 8, 2022

Thanks for working on our feedback, we will close this issue and look forward to see the outcome on WICG/client-hints-infrastructure#103 If there are problems working on it, please reopen this issue.

@ylafon ylafon closed this as completed Apr 8, 2022
@ylafon ylafon added Resolution: satisfied The TAG is satisfied with this design and removed Progress: propose closing we think it should be closed but are waiting on some feedback or consensus chromium-high-priority Something that the Chromium team would like the TAG to prioritise labels Apr 8, 2022
@arichiv
Copy link
Author

arichiv commented May 31, 2022

After feedback from Cloudinary (WICG/client-hints-infrastructure#108) we're considering a few options for how to improve the HTML accept-ch delegation. Specifically, the current syntax does not conform to either the Permissions-Policy: ... HTML format nor the <iframe allow="..."/> format. We are considering the following options:

  1. Keep current format
  • <meta name="accept-ch" content="sec-ch-dpr=(https://foo.bar/), sec-ch-width=(https://foo.bar/)">
  1. Support quotes (like PermissionsPolicy HTTP Header)
  • <meta name="accept-ch" content="sec-ch-dpr=('https://foo.bar/'), sec-ch-width=('https://foo.bar/')">
  1. Support iframe allow like format
  • <meta name="accept-ch" content="sec-ch-dpr https://foo.bar/; sec-ch-width https://foo.bar/">
  1. Require http-equiv accept-ch and add delegate-ch
  • <meta http-equiv="accept-ch" content="sec-ch-dpr, sec-ch-width">
  • <meta name="delegate-ch" content="ch-dpr https://foo.bar/; ch-width https://foo.bar/">

Options 1 and 4 are preferred given the we are doing double duty (both requesting and delegating client hints). Mimicking the Permissions-Policy (option 2) or iframe allow (option 3) formats might obscure the distinct meaning of this code.

I can start a new thread if needed, but this seemed a good place to start. https://bugs.chromium.org/p/chromium/issues/detail?id=1330554

@ylafon @eeeps @yoavweiss @domenic

@yoavweiss
Copy link

The advantage of (4) from my perspective is that we're keeping a single markup for delegation and allow attributes (including the same policy names). The disadvantage is that developers would need to both opt-in the current page and delegate the hints, so would need to add 2 separate bits of markup.

@eeeps - I'd love your opinions on the above tradeoff

@domenic
Copy link
Member

domenic commented May 31, 2022

Are the [s above some sort of typo, or are they part of the format?

@arichiv
Copy link
Author

arichiv commented Jun 1, 2022

Are the [s above some sort of typo, or are they part of the format?

Sorry that was a copypasta error; fixed.

@domenic
Copy link
Member

domenic commented Jun 1, 2022

2. Support quotes (like PermissionsPolicy HTTP Header)

This is not actually like the PermissionsPolicy HTTP header, right? Since the header is a structured header and thus must use double quotes, not the single quotes you show here.

4. Require http-equiv accept-ch and add delegate-ch

So, the difference between meta name and meta http-equiv is a real mess already, but I think this proposal makes it even worse. In general how things are supposed to work is:

  • http-equiv should be used for all "pragmas" that modify the processing model
  • name should be used for all "document-level metadata" that does not modify any processing model
  • To avoid any confusion, people should try to never put HTTP header-like things in http-equiv, despite the name. (Because of the 7 specified pragma directives, only 1 has equivalent behavior to the corresponding HTTP header. So either adding something equivalent to the HTTP header, or something non-equivalent with the same name, just makes things worse.)

This is not really well-followed, e.g. name="referrer" definitely modifies the processing model, and arguably so does name="color-scheme". But those cases were not discussed with the HTML community before they were implemented everywhere. So since you're asking ahead of time this time, maybe you're interested in sticking to the desired architecture.

So with that in mind, from a HTML perspective the best idea might be something like (5), a http-equiv value whose value space allows you to do both things at once, but definitely doesn't look like any header syntax? Maybe something like <meta http-equiv="delegated-ch" content="sec-ch-dpr https://foo.bar/; sec-ch-width https://foo.bar/">?

@arichiv
Copy link
Author

arichiv commented Jun 1, 2022

The question then becomes: is the benefit of having something like (5) worth changing the syntax? From where I stand, (1) is functionally identical and the benefits of switching aren't clear given either way developers need to learn a semi-unique syntax.

@yoavweiss
Copy link

@arichiv - I may be wrong, but I think the syntax @domenic is proposing is similar to the "allow" attribute syntax, so that somewhat reduces the uniqueness.

In general how things are supposed to work is:

  • http-equiv should be used for all "pragmas" that modify the processing model
  • name should be used for all "document-level metadata" that does not modify any processing model
  • To avoid any confusion, people should try to never put HTTP header-like things in http-equiv, despite the name. (Because of the 7 specified pragma directives, only 1 has equivalent behavior to the corresponding HTTP header. So either adding something equivalent to the HTTP header, or something non-equivalent with the same name, just makes things worse.)

Embarassing, but I did not know that. Thanks @domenic for pointing that out.

@arichiv
Copy link
Author

arichiv commented Jun 7, 2022

Thanks for the feedback! On it for M105 WICG/client-hints-infrastructure#108 (comment)

@arichiv
Copy link
Author

arichiv commented Jun 14, 2022

@ylafon / @torgo
Can this be re-opened? We're revising this proposal with updated syntax: https://groups.google.com/a/chromium.org/g/blink-dev/c/cGOjmfOamsE

Old:
<meta name="accept-ch" value="sec-ch-dpr=(https://foo.bar/ https://baz.qux), sec-ch-width=(https://foo.bar)">

New:
<meta http-equiv="delegate-ch" value="sec-ch-dpr https://foo.bar https://baz.qux; sec-ch-width https://foo.bar">

We’re switching from name="accept-ch" to http-equiv="delegate-ch" on advice that http-equiv should be used when the value is impacting the processing model. We’re switching from syntax close to HTTP Permissions-Policy to use syntax closer to the iframe allow attribute at the request of developers.

Although this change is coming after a launch in M100, usage of the prior syntax is low (currently 0.000016%) and it seems worth taking the opportunity to reduce developer confusion and increase standards compliance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants