Page MenuHomePhabricator

Move the time limit check before the permissions check
Closed, ResolvedPublicSecurity

Description

What is the problem?

As pointed out by @Dreamy_Jazz in T342790#9073530:

To combat the time that a user has to investigate whether a deleted revision was made by them, the check that ensures the API call was made within the last 30 minutes (T342134) could be placed before the check if the performer of the action is deleted.

Otherwise, if you didn't have permission to see the editor of a revision, you could infer whether or not it was created by you (or someone using the same IP as you) depending on what error you got back from the server. If the editor was not you (or your IP) you would fail the permission check and be told you were not the creator of the revision. If the editor was you, you would pass the permission check but fail the timeout check.

Steps to reproduce problem
  1. Install CheckUser (client hints will be enabled by default)
  2. In your LocalSettings.php, add $wgCheckUserClientHintsRestApiMaxTimeLag = 5;
  3. Make two edits to a page with Firefox, one logged out and one logged in
  4. Record the revision IDs of the two edits
  5. Login as an admin, go to the history of the page you just edited
  6. Check the checkboxes next to the two edits and click "Change visibility of selected revisions"
  7. Next to "Editor's username/IP address" check the "Hidden" radio button and submit
  8. Run these two commands, replacing <rev id logged out> and <rev id logged in> with the IDs you found in step 4
curl 'http://localhost:8080/w/rest.php/checkuser/v0/useragent-clienthints/revision/<rev id logged out>' -H 'Content-Type: application/json' --data-raw '{"architecture":"","bitness":"64","brands":[{"version":"24","brand":"Not)A;Brand"},{"brand":"Chromium","version":"116"}],"fullVersionList":[{"version":"24.0.0.0","brand":"Not)A;Brand"},{"brand":"Chromium","version":"116.0.5845.96"}],"mobile":false,"model":"","platform":"Linux","platformVersion":"5.10.0"}'

curl 'http://localhost:8080/w/rest.php/checkuser/v0/useragent-clienthints/revision/<rev id logged in>' -H 'Content-Type: application/json' --data-raw '{"architecture":"","bitness":"64","brands":[{"version":"24","brand":"Not)A;Brand"},{"brand":"Chromium","version":"116"}],"fullVersionList":[{"version":"24.0.0.0","brand":"Not)A;Brand"},{"brand":"Chromium","version":"116.0.5845.96"}],"mobile":false,"model":"","platform":"Linux","platformVersion":"5.10.0"}'

Expected behavior: Both should return The revision <rev id> is too old to allow recording client hints data
Observed behavior:

  • The <rev id logged out> command returns The revision <rev id> is too old to allow recording client hints data
  • The <rev id logged in> command returns User 0 is not the author of revision <rev id>
Environment

Wiki(s): CheckUser 2.5 (999417f) 13:47, 28 August 2023.

QA Results - Local

Details

Event Timeline

@dom_walden can I confirm that the second bullet point was made while logged in? Just that the code should provide the ID of the user making the request, which for a logged in user should not be 0.

@dom_walden can I confirm that the second bullet point was made while logged in? Just that the code should provide the ID of the user making the request, which for a logged in user should not be 0.

It would have been while logged out. I send the curl requests without any cookies so I guess it just uses the IP address to identify the user. I suppose my reproduction steps could make that more explicit. The edit in step 3 needs to be done from the same IP address that you are running curl from (which I assume will be for most people?)

@dom_walden can I confirm that the second bullet point was made while logged in? Just that the code should provide the ID of the user making the request, which for a logged in user should not be 0.

It would have been while logged out. I send the curl requests without any cookies so I guess it just uses the IP address to identify the user. I suppose my reproduction steps could make that more explicit. The edit in step 3 needs to be done from the same IP address that you are running curl from (which I assume will be for most people?)

Thanks for the clarification. I think I just read the instructions and then assumed the information without thinking.

I don't think this needs a security deploy because this only leaks info if:

  • You are editing while logged out
  • You use exactly the same IP address as the editor that had the edit suppressed

This means (except from the user who made the edit seeing they made the edit) this is only really possible to occur when the IP being used is some kind of proxy. This means this won't be the users' actual IP.

Furthermore, this issue is already publicly stated and has been for a while.

This still probably needs to be fixed, but this can probably be done without the need for a security patch.

@sbassett What you think about making this task public and fixing the issue normally based on my comments in T345165#9127248?

@sbassett What you think about making this task public and fixing the issue normally based on my comments in T345165#9127248?

Yes, I think this seems like a pretty minor Vuln-Infoleak IMO.

This means (except from the user who made the edit seeing they made the edit) this is only really possible to occur when the IP being used is some kind of proxy. This means this won't be the users' actual IP.

Or a shared device, in which case, I can't think of an example where a user wouldn't already confidently know or very strongly suspect who the other users were. And I don't really know what direct advantage could be gained from someone knowing that another person, somewhere in the world, using the same proxy service that they use, made an edit. Still, this would be a good thing to clean up at some point.

sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".
sbassett changed the edit policy from "Custom Policy" to "All Users".
sbassett changed Risk Rating from N/A to Low.

Change 954901 had a related patch set uploaded (by Dreamy Jazz; author: Dreamy Jazz):

[mediawiki/extensions/CheckUser@master] clienthints: Perform timestamp check before user check in REST API

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

Change 954901 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Perform timestamp check before user check in REST API

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

@Dreamy_Jazz The revision <rev id> did come back as too old to allow recording client hints data when the time expired. We also talked about the statement within the time for the 2nd part as expected. I will move this to Done. Thanks for all your work!

Status: ✅ PASS
Environment: Local: 1.41.0-alpha (30b06ec)14:14, 6 September 2023. CheckUser: 2.5 (9c96054) 10:22, 6 September 2023
OS: macOS Ventura
Browser: Chrome 116
Device: MBP
Emulated Device:: N/A
Test Link
http://localhost:8080/w/index.php?title=Dog&action=history

✅AC1: Both should return The revision <rev id> is too old to allow recording client hints data

Change VisbilityTime Lag ExpiredWithin Time Lag
2023-09-06_08-17-33.png (858×1 px, 227 KB)
2023-09-06_08-13-26.png (185×1 px, 80 KB)
2023-09-06_08-24-51.png (169×1 px, 78 KB)