Page MenuHomePhabricator

CVE-2024-47847: Various XSSes found in Cargo
Closed, ResolvedPublicSecurity

Description

Steps to replicate the issue (include links if applicable):

  • Install MediaWiki and Cargo (making sure to use https://gerrit.wikimedia.org/r/q/I77d6013c7d5acda90fca47cb23d2a106670d421f as that fixes a bug that causes XSS 4 to fail)
  • Import the following backup:
  • Upload a file with the filename "html.png" (not sure if this is required, but too lazy to test)
  • Create cargo tables for Template:Cargo, Template:Cargo/file, and Template:Cargo/allowedvalues
  • See heading "XSS reproduction paths"

XSSes:

  • XSS 1 (DOM-based, requires (editinterface)): System message cargo-viewdata-tablestooltip
  • XSS 2 (DOM-based, requires (editinterface)): System message cargo-viewdata-orderbytooltip
  • XSS 3 (DOM-based, requires (editinterface)): System message show
  • XSS 4 (DOM-based, requires (editinterface)): System message cargo-cargotables-columncountinfo
  • XSS 5 (DOM-based): HTTP query parameter header_tooltips
  • XSS 6 (DOM-based, requires (editinterface), cannot use <>, requires user interaction): System message cargo-dynamictables-searchcolumn
  • XSS 7 (DOM-based, requires (editinterface), requires user interaction): System message cargo-recreatedata-success (and probably everything in ext.cargo.recreatedata.js)
  • XSS 8 (stored, requires (editinterface)): System message cargo-cargotables-mandatory
  • XSS 9 (reflective): HTTP query parameter delimiter
  • XSS 10 (reflective): HTTP query parameter filename
  • XSS 11 (reflective): HTTP query parameter link_text
  • XSS`12 (stored, requires (editinterface)): System message cargo-pagevalues-tablevalues
  • XSS 13 (stored): Allowed values in a table
  • XSS 14 (stored, requires (editinterface)): System message cargo-field-type
  • XSS 15 (stored, requires (editinterface)): System message cargo-allowed-values
  • XSS 16 (stored, requires (editinterface)): System message cargo-cargotables-replacementtable
  • XSS 17 (stored, requires (editinterface)): System message returnto
  • XSS 18 (stored, requires (editinterface)): System message cargo-switchtables-confirm

XSS reproduction paths:

  • /wiki/Special:CargoQuery: XSS 1, XSS 2
  • /wiki/Special:CargoTables/cargo: XSS 3, XSS 8
  • /wiki/Special:CargoTables: XSS 4
  • /wiki/Special:CargoQuery?tables=cargo&fields=_pageName&format=dynamic+table&header_tooltips=<script>alert("awawa (xss 5)")</script>: XSS 1, XSS 2, XSS 5
  • /wiki/Special:CargoQuery?tables=cargo&fields=_pageName&format=dynamic+table&searchable_columns=yes: XSS 1, XSS 2, XSS 6
  • /wiki/Template:Cargo?action=recreatedata: XSS 7
  • /wiki/Special:CargoQuery?tables=cargo&fields=_pageName&format=list&delimiter=<script>alert("the+fight+against+the+eep...+(xss+9)")</script>: XSS 1, XSS 2, XSS 9
  • /wiki/Special:CargoQuery?tables=cargofile&fields=file&format=zip&filename=">awawa<%2Fdiv><script>alert("xss+in+filename+%3A3+(xss+10)")<%2Fscript><div+a&link_text=<script>alert("xss+in+link+text+%3A)+(xss+11)")<%2Fscript>: XSS 1, XSS 2, XSS 10, XSS 11
  • /wiki/Special:PageValues/cargo: XSS 12, XSS 14
  • /wiki/Special:CargoTables/cargoallowedvalues: XSS 13
  • /wiki/Special:PageValues/Cargo/allowedvalues: XSS 3, XSS 12, XSS 13, XSS 14, XSS 15
  • /wiki/Special:CargoTables/cargo?_replacement (requires replacement table): XSS 3, XSS 8, XSS 16
  • /wiki/Special:DeleteCargoTable/cargo?_replacement (on Delete, requires replacement table): XSS 17
  • /wiki/Special:SwitchCargoTable/cargo (requires replacement table): XSS 18
  • /wiki/Special:SwitchCargoTable/cargo (on Switch, requires replacement table): XSS 17

Software version (on Special:Version page; skip for WMF-hosted wikis like Wikipedia):

  • MediaWiki: 1.42.1 (523b312) 15:03, 1 August 2024
  • PHP: 8.1.20 (fpm-fcgi)
  • MariaDB: 11.4.2-MariaDB
  • Cargo: 3.6.1 (6b8d1eb) 10:34, 10 August 2024

Other information (browser name/version, screenshots, etc.):
XSS 4 requires a patched Cargo (change ID I77d6013c7d5acda90fca47cb23d2a106670d421f), as the code susceptible to the DOM-based XSS fails to load otherwise.

Miraheze issue tracker task: https://issue-tracker.miraheze.org/T12453

Video of me demonstrating all the XSSes: https://phorge-static.wikitide.net/file/data/73lu74ajmi2nj6pdeoww/PHID-FILE-2jhjxuatrm634yfkqp52/cargo-xsses.mp4

Details

Risk Rating
Medium
Author Affiliation
Wikimedia Communities

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

@BlankEclair thank you for reporting. I'll follow up with further information soon

@BlankEclair - thank you for this very detailed analysis, and the video, and the patch! This is extremely helpful. (And I had no idea that there were this many unescaped messages and other strings!) Unfortunately, I didn't see the patch until now - by which time I had already written up fixes on my own for most of these issues. Although in many cases our fixes are (as maybe could be expected) very similar to one another's, and in some cases your fixes are a little more elegant. Anyway, I'm going through the issues piecemeal, and here is the first of my changes:

eee69a311d12

It takes care of all the JS-related issues, as far as I know; and it basically has the same approach you took, of replacing hardcoded HTML.

By the way, the one issue I can't reproduce is #6, with cargo-dynamictables-searchcolumn - it's possible that this is really just one of the other issues in disguise, or something. Maybe after the rest after the rest are fixed, we can see if this is still a problem.

Here's another change, which I think fixes issues 14 and 15, and also some new long-overdue i18n messages: 62b150dca2bb

It takes care of all the JS-related issues, as far as I know; and it basically has the same approach you took, of replacing hardcoded HTML.

XSS 5 is still reproducible. To repeat the example path: /wiki/Special:CargoQuery?tables=cargo&fields=_pageName&format=dynamic+table&header_tooltips=<script>alert("awawa (xss 5)")</script>
XSS 6 is also reproducible, but that's understandable since you couldn't figure it out.

Also, you appended the wrong variable here (viewTableText instead of viewTableTag): https://phabricator.wikimedia.org/diffusion/ECRG/browse/master/libs/ext.cargo.recreatedata.js;62b150dca2bbe90ff9544959315650d739a5e98e$83

By the way, the one issue I can't reproduce is #6, with cargo-dynamictables-searchcolumn - it's possible that this is really just one of the other issues in disguise, or something. Maybe after the rest after the rest are fixed, we can see if this is still a problem.

You can't use <> to break out of the input element, but quotes are not escaped. Therefore, you could use something like " style="position: fixed; top: 0; left: 0; height: 100%; width: 100%;" onmouseover="alert('xss in mediawiki:cargo-dynamictables-searchcolumn uwu (xss 6)') to break out of the attribute value and add extra attributes to the element.

Sorry - by "JS-related issues", I meant issues where the fix needs to be in the JavaScript code, rather than in PHP.

Thanks for pointing out that incorrect variable! That was due to a last-minute renaming. I fixed it at 2da55512ff85.

And thanks for pointing out the issue with #6. I had no idea that apparently neither Message::parse(), not Html::element(), escapes quotes... that was very good to know.

I just checked in what I think is the final fix for these XSS issues, based in part on your patch, and of course on your other feedback here, at, 1144d41c0d80. Please let me know if everything is indeed fixed!

Sorry - by "JS-related issues", I meant issues where the fix needs to be in the JavaScript code, rather than in PHP.

Basically DOM-based XSSes, right?

Also, using Message::parse() is safe as element values since it's basically rendered wikitext. This means that you didn't need to replace ->parse() with ->escaped() in https://phabricator.wikimedia.org/rECRG1144d41c0d804b38ddd331617236bf6ea43f9e48#change-pzEF3usdN8Mg (which leads to this bug):

Screenshot 2024-08-17 at 13-59-55 View replacement tabl[...].png (124×2 px, 81 KB)

Also, XSS 12 and XSS 13 are not patched.

Reassigning to Yaron as he is doing the patches by himself (and perhaps being inspired by mine) rather than simply applying the one I posted.

Thanks for pointing out these problems. Clearly I was over-optimistic before! I believe I've now taken care of the remiaining issues in dfe25479c450 and 8ca19783349d - though of course I could be wrong.

As for parse() vs. escaped() - I was told a while ago that escaped() is better to use than parse(), if the purpose is just to avoid XSS leaks, because it runs faster. Although obviously sometimes parse() is needed, as we've seen.

/wiki/Special:PageValues/Cargo/allowedvalues is still vulnyable to XSS 13:

2024-08-20_00-00.png (841×1 px, 321 KB)

The issue with the system message cargo-cargotables-deletereplacement not having its wikitext parsed is still present. Also, Special:DeleteCargoTable/cargo (when deleting) has double-escaped entities:

awawa.png (256×1 px, 45 KB)

(But yes, Message::escaped() is (probably marginally) faster than Message::parse() since the former only needs to retrieve and escape the message, while the latter needs to put it through the parser).

It never ends! Thank you for your continued patience. I think I've fixed everything now with d60319b19027 and 59af70a2ec87, but I'm looking forward to finding out...

Thank you. I've now requested that Miraheze update the extension on their end, and they (or I) will comment on this task when done.

sbassett changed Author Affiliation from N/A to Wikimedia Communities.Aug 20 2024, 1:57 PM
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.
Mstyles renamed this task from Various XSSes found in Cargo to CVE-2024-47847: Various XSSes found in Cargo.Oct 5 2024, 12:47 AM