Page MenuHomePhabricator

Implement support for requesting client hint header
Closed, ResolvedPublic

Description

In T257893: [EPIC] Support User-Agent Client Hints header in CheckUser we decided that we want to request high entropy user agent data via the client hints header for actions that are interesting to Extension:CheckUser: editing, creating an account, logging in, etc.

In this task, we'll do the work to implement setting the header.

  • For page requests, we should be able to use BeforePageDisplay hook in Extension:CheckUser to see if the user is on a page that meets criteria for requesting client hint data on subsequent requests.
  • For API editing, we use the postEdit hook and the client-side JS API getHighEntropyValues(), and POST the results to an endpoint in CheckUser extension, /checkuser/v0/useragent-clienthints/{revision}

Ensure client hints header is requested when user begins these workflows:

  • [web] Special:CreateAccount
  • [web] Special:UserLogin
  • [web] Special:UserLogout
  • [web] Special:PasswordReset
  • [web] Special:EmailUser
  • [web] ?action=edit/undo/rollback ?action=history (for rollback and undo)
  • [API] edit handled via postEdit mw.hook (as is non-API editing)

Event Timeline

Restricted Application added a subscriber: Aklapper. ยท View Herald TranscriptJun 1 2023, 2:39 PM
kostajh changed the task status from Open to In Progress.Jun 1 2023, 3:13 PM
kostajh claimed this task.

Change 926462 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Hook handler, config, and SpecialPage integration

https://gerrit.wikimedia.org/r/926462

Change 926483 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[operations/mediawiki-config@master] checkuser: Disable client hints feature by default

https://gerrit.wikimedia.org/r/926483

Change 927166 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Request on ?action query parameter

https://gerrit.wikimedia.org/r/927166

Change 927242 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Send empty header on page views

https://gerrit.wikimedia.org/r/927242

Change 926483 merged by jenkins-bot:

[operations/mediawiki-config@master] checkuser: Disable client hints feature by default

https://gerrit.wikimedia.org/r/926483

Mentioned in SAL (#wikimedia-operations) [2023-06-06T07:14:41Z] <kharlan@deploy1002> Started scap: Backport for [[gerrit:926483|checkuser: Disable client hints feature by default (T337944)]]

Mentioned in SAL (#wikimedia-operations) [2023-06-06T07:16:09Z] <kharlan@deploy1002> kharlan: Backport for [[gerrit:926483|checkuser: Disable client hints feature by default (T337944)]] synced to the testservers: mwdebug1001.eqiad.wmnet, mwdebug2002.codfw.wmnet, mwdebug1002.eqiad.wmnet, mwdebug2001.codfw.wmnet

Mentioned in SAL (#wikimedia-operations) [2023-06-06T07:22:55Z] <kharlan@deploy1002> Finished scap: Backport for [[gerrit:926483|checkuser: Disable client hints feature by default (T337944)]] (duration: 08m 14s)

Change 926462 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Hook handler, config, and SpecialPage integration

https://gerrit.wikimedia.org/r/926462

Change 927166 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Request on ?action query parameter

https://gerrit.wikimedia.org/r/927166

Change 927242 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Send empty header on page views

https://gerrit.wikimedia.org/r/927242

kostajh updated the task description. (Show Details)

I've removed "[API] account creation" from the list of use cases. I'm not aware of a workflow where one creates an account via the create account API module while using the browser.

For API editing, what I hoped was:

  • user visits /wiki/SomeArticle
  • Server doesn't request client hints header data
  • user clicks "Edit" (VisualEditor) and Chrome makes an API request to visualeditor API module
  • CheckUser hook in ApiBeforeMain sets the header to accept user-agent client hints
  • user POSTs the Edit, Chrome was instructed in the previous API request to send this data
  • POST request contains user-agent client hint data

But, it appears that if you request a document that doesn't request user-agent headers, and then you request user-agent client hints in an API request on that page, Chrome will ignore the header request, I guess because it is only looking at headers sent for the GET or POST to the document. ๐Ÿ˜ข

My current thought is to implement a VisualEditor plugin in CheckUser; the plugin would use Chrome's JS API NavigatorUAData.getHighEntropyValues()), and on VisualEditor edit, it would pass the high entropy values as plugin data. CheckUser would then implement onVisualEditorApiVisualEditorEditPostSave or onVisualEditorApiVisualEditorEditPreSave to store the data.

I'm not sure if DiscussionTools supports plugins, though. And then there's also StructuredDiscussions and possibly other JS + API editing interfaces (Wikibase?) we want to support.

An earlier suggestion in T257893: [EPIC] Support User-Agent Client Hints header in CheckUser was to request client hint headers on all logged-in user requests, but that means that we would not have user-agent client hint data for anonymous users who use JS+API interfaces for editing (VisualEditor/DiscussionTools/Flow), so I don't think requesting the header for all logged-in user requests is a good solution.

Maybe what we can do with minimum of effort and greatest impact is:

  • write the VE plugin in CheckUser and pass the contents of NavigatorUAData.getHighEntropyValues() as plugin data parameters; CheckUser can use a post-save VisualEditor hook to handle storage. Maybe it's also straightforward to implement some basic plugin support for DiscussionTools, we'll need to talk to Editing-team
  • server-side: always request user-agent client headers for talk namespaces, for anonymous and logged-in users. That way, if the user starts using DiscussionTools or VisualEditor on those namespaces, we'll have access to the user agent client hint data when the user POSTs their edit. We unset the client hint header on pages/namespaces we don't want to check, and we wouldn't store this data unless the user makes a POST, so I think this is OK from a privacy perspective
  • server-side: always request user-agent client headers for Flow content model pages, same justification as previous point

Change 928531 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Simplify, rework test

https://gerrit.wikimedia.org/r/928531

Change 928532 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Don't request client hints on POST requests

https://gerrit.wikimedia.org/r/928532

Change 928531 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Simplify, rework test

https://gerrit.wikimedia.org/r/928531

Change 928848 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] [WIP] clienthints: Integrate with VisualEditor

https://gerrit.wikimedia.org/r/928848

Another option would be to use the postEdit hook which VE and DiscussionTools fire. Subscribe to the hook event, use the JS API to collect the client hint data, then POST that to a CheckUser API endpoint using the revision that the user just made. We'd need to modify the postEdit hook to include the revision ID generated as part of the edit, though. But I imagine that is a lot less work than implementing plugin support for DiscussionTools and adding a separate implementation for Flow.

Change 929401 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Send high entropy data on postEdit hook

https://gerrit.wikimedia.org/r/929401

Change 928848 abandoned by Kosta Harlan:

[mediawiki/extensions/CheckUser@master] clienthints: Send with VisualEditor edits

Reason:

See I3a52ea7597c045142201a1f966dcf4e407d07104

https://gerrit.wikimedia.org/r/928848

Change 929403 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Request headers on action=history instead of rollback

https://gerrit.wikimedia.org/r/929403

Change 929403 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Request headers on action=history instead of rollback

https://gerrit.wikimedia.org/r/929403

Change 928532 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Don't request client hints on POST requests

https://gerrit.wikimedia.org/r/928532

Change 929990 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Don't ask for client hint data on ?action=edit

https://gerrit.wikimedia.org/r/929990

Change 929992 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Check if browser supports client hints

https://gerrit.wikimedia.org/r/929992

Change 929401 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Send high entropy data on postEdit hook

https://gerrit.wikimedia.org/r/929401

Change 929990 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Don't ask for client hint data on ?action=edit

https://gerrit.wikimedia.org/r/929990

Change 929992 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Check if browser supports client hints

https://gerrit.wikimedia.org/r/929992

kostajh updated the task description. (Show Details)
kostajh changed the task status from In Progress to Open.Jun 21 2023, 7:27 AM
kostajh updated the task description. (Show Details)

Testing notes

Testing should be done locally, with a recent version of Chrome.

Special pages:
Detailed QA steps for testing client hints are requested/sent when visiting special pages can be found in: https://gerrit.wikimedia.org/r/c/mediawiki/extensions/CheckUser/+/926462/6//COMMIT_MSG

Actions:
Similar to the above, but instead of visiting a special page, visit a page with action=history, then attempt undo or rollback. Client hint headers should be sent with the request that performs the undo/rollback.

API:

  • Make an edit via the source editor, VisualEditor, or DiscussionTools, with the Network tab open in developer tools
  • Check that an API request was sent to /checkuser/v0/useragent-clienthints/{revision}, containing the client hint data in the payload

Browsers that don't support client hints:
In browsers that don't support client hints (e.g. Firefox), no client hint headers should be returned in the responses, and no API request should be made to checkuser

Change 932003 had a related patch set uploaded (by Kosta Harlan; author: Kosta Harlan):

[mediawiki/extensions/CheckUser@master] clienthints: Log REST errors in English

https://gerrit.wikimedia.org/r/932003

Thanks @kostajh and @Tchanders! I came across no issues as seen in the screenshots below. I will move this to Done, thanks again!

Main Page- No Accept-Ch`

T337944_ClientHintHeader_MainHeader1.png (1ร—3 px, 297 KB)

Main Page- Sec-Ch-Ua`

T337944_ClientHintHeader_MainHeader2.png (1ร—3 px, 351 KB)

Create Account- Sec-Ch-Ua` - Blank Username

T337944_ClientHintHeader_CreateAccount1.png (1ร—3 px, 395 KB)

Create Account- Sec-Ch-Ua` - Populated Username

T337944_ClientHintHeader_CreateAccount2.png (1ร—3 px, 426 KB)

Undo- Clint Hint Headers

T337944_ClientHintHeader_Undo.png (1ร—3 px, 397 KB)

API Request Payload

T337944_ClientHintHeader_APIRequestPayload.png (1ร—1 px, 462 KB)

Change 932003 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Log REST errors in English

https://gerrit.wikimedia.org/r/932003