Page MenuHomePhabricator

ReportIncident REST API does not use a CSRF token
Closed, ResolvedPublic1 Estimated Story PointsSecurity

Assigned To
Authored By
Dreamy_Jazz
Jan 30 2024, 3:49 PM
Referenced Files
F41736334: image.png
Feb 1 2024, 12:07 AM
F41736365: image.png
Feb 1 2024, 12:07 AM
F41736340: image.png
Feb 1 2024, 12:07 AM
F41735266: image.png
Jan 31 2024, 5:15 PM
F41735256: image.png
Jan 31 2024, 5:15 PM
F41735253: image.png
Jan 31 2024, 5:15 PM
F41735085: image.png
Jan 31 2024, 5:15 PM
F41732538: T356190.patch
Jan 30 2024, 10:36 PM

Description

The Incident-Reporting-System extension provides a REST API used to make incident reports. These reports are made via a POST request and cause an email to be sent with the contents of the report after validation and rate limiting.

However, this REST API does not validate a CSRF token and nor does it require that the user making the request use a session that is safe from CSRF (such as OAuth).

Event Timeline

Proposed patch (passes on my local environment):

This extension is not deployed on production, so once this has been given a +2 we can upload this to gerrit and submit it through CI (the tests passed for me locally, but I can't be sure they will pass in CI until it has been publicly uploaded).

Dreamy_Jazz set the point value for this task to 1.Jan 30 2024, 11:41 PM

Proposed patch (passes on my local environment):

This extension is not deployed on production, so once this has been given a +2 we can upload this to gerrit and submit it through CI (the tests passed for me locally, but I can't be sure they will pass in CI until it has been publicly uploaded).

Virtual +2, but I also think this could be handled in Gerrit publicly, as the extension isn't in production.

From T333569#8742962:

... anything within the supplemental release can be made public and have backports performed once the issue has been patched in Wikimedia production

Therefore, I think uploading this to Gerrit and giving it a +2 is fine as this extension is not deployed on WMF production (therefore it cannot be patched there) and is not bundled.

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

[mediawiki/extensions/ReportIncident@REL1_41] SECURITY: Use a CSRF token in the ReportIncident REST API

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

Change 994687 merged by jenkins-bot:

[mediawiki/extensions/ReportIncident@master] SECURITY: Use a CSRF token in the ReportIncident REST API

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

Given the virtual +2 I uploaded the patch to Gerrit and made a small change to allow the selenium tests to pass. I then backported it and +2'd that backport.

Change 994693 merged by jenkins-bot:

[mediawiki/extensions/ReportIncident@REL1_41] SECURITY: Use a CSRF token in the ReportIncident REST API

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

Virtual +2, but I also think this could be handled in Gerrit publicly, as the extension isn't in production.

Yes, the Security-Team would consider this low risk.

Suggested QA steps for a local wiki (let me know if you would like steps for patchdemo wikis):

  1. Install Incident-Reporting-System extension, if required
  2. Verify that you have $wgReportIncidentRecipientEmails, $wgReportIncidentEmailFromAddress, and $wgReportIncidentDeveloperMode = true; defined in your LocalSettings.php. If not, you can add the following:
$wgReportIncidentRecipientEmails = [ 'test@example.com' ];
$wgReportIncidentEmailFromAddress = 'no-reply@example.com';
$wgReportIncidentDeveloperMode = true;
  1. Login to an account and go to an existing user talk page
  2. Click Report in the Tools menu
  3. Open up Developer Tools (F12) and open the network tab
  4. Fill out the form and press submit. Ensure that the request is successful (and if not fix the errors to address this).
  5. Find the successful request in the network tab. On Chrome this should be the last request and the name of the request should be report and will look something like the below screenshot:

image.png (93×1 px, 9 KB)

  1. Click on the request and find the request body (on Chrome this is called Payload). Ensure that a token key is present with a defined string value. For example the token is surrounded by a red box in the below screenshot:

image.png (210×1 px, 26 KB)

  1. Right click on the request and click "Copy as fetch" (in the Copy sub-menu on Chrome)
  2. To go the browser console and paste from your clipboard. This should look something like the following:

image.png (514×1 px, 58 KB)

  1. Modify add characters to the string that is wrapped in the characters \" after \"token\". For example, on my wiki this means that the text in the console now looks like:

image.png (520×1 px, 59 KB)

  1. Run this command and go back to the network tab
  2. Find the last request in that window and open it.
  3. Verify that the response to the request is the following:
{
    "errorKey": "rest-badtoken",
    "messageTranslations": {
        "en": "The CSRF token provided is invalid."
    },
    "httpCode": 403,
    "httpReason": "Forbidden"
}

I have verified that the new code has been implemented and is functioning and displaying as expected...

Thank you @Dreamy_Jazz.

image.png (459×1 px, 248 KB)

image.png (256×617 px, 33 KB)

image.png (273×976 px, 57 KB)

@kostajh should this task be made public before this is marked as resolved?

@kostajh should this task be made public before this is marked as resolved?

I am not sure if it matters.

@kostajh should this task be made public before this is marked as resolved?

I am not sure if it matters.

It's fine to make this task public now. I'd agree that the order of resolving vs. making public doesn't really matter.

sbassett triaged this task as Medium priority.Feb 1 2024, 4:14 PM
sbassett changed Author Affiliation from N/A to WMF Product.
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 Medium.
sbassett moved this task from Incoming to Watching on the Security-Team board.

Test wiki created on Patch demo by DJacksonA using patch(es) linked to this task:
https://patchdemo.wmflabs.org/wikis/2868537a3b/w