In the Wikistories extension, multiple system messages are inserted as raw HTML, allowing for stored XSS.
## wikistories-story-selecttext
### Reproduction
1. Install Wikistories as described in https://www.mediawiki.org/wiki/Extension:Wikistories#Install and https://www.mediawiki.org/wiki/Extension:Wikistories#Running_locally
2. Edit `MediaWiki:Wikistories-story-selecttext` to `<img src="" onerror="alert('wikistories-story-selecttext')">`
3. Go to `/wiki/Special:StoryBuilder/Main_Page`
4. Select any image
5. Click the blue ">" button
{F65677396}
### Cause
The system message is retrieved using the text output mode and then inserted as raw HTML using v-html:
https://gerrit.wikimedia.org/g/mediawiki/extensions/Wikistories/+/5907351fd2a971ab9839391bf93a3caf3766c5e5/resources/ext.wikistories.builder/components/StoryTextbox.vue#32
## wikistories-story-edittext-duplicate
### Reproduction
1. Install Wikistories as described in https://www.mediawiki.org/wiki/Extension:Wikistories#Install and https://www.mediawiki.org/wiki/Extension:Wikistories#Running_locally
2. Edit `MediaWiki:Wikistories-story-edittext-duplicate` to `<img src="" onerror="alert('wikistories-story-edittext-duplicate')">`
3. Go to `/wiki/Special:StoryBuilder/Main_Page`
4. Select any image
5. Click the blue ">" button
6. Click on the white text box at the bottom of the image
7. Select any text on the main page, for example "Community portal – The central hub for editors, with resources, links, tasks, and announcements."
8. Click "Add to story"
9. Click the "+" button at the bottom right corner of the image
10. Select any image
11. Click the blue ">" button
12. Click on the white text box at the bottom of the image
13. Select the same text you selected in step 7
14. Click "Add to story"
{F65677416}
### Cause
The message is retrieved through mw.msg(), implicitly using the text output mode:
https://github.com/wikimedia/mediawiki-extensions-Wikistories/blob/5907351fd2a971ab9839391bf93a3caf3766c5e5/resources/ext.wikistories.builder/store/story.js#L186
The message is then inserted as raw HTML using v-html:
https://github.com/wikimedia/mediawiki-extensions-Wikistories/blob/5907351fd2a971ab9839391bf93a3caf3766c5e5/resources/ext.wikistories.builder/components/StoryTextbox.vue#L22
## wikistories-story-edittext-outdated
### Reproduction
This should also be reproducible without editing the JS, but for convenience, I've used the hack in step 2 to get the warning to show up.
1. Install Wikistories as described in https://www.mediawiki.org/wiki/Extension:Wikistories#Install and https://www.mediawiki.org/wiki/Extension:Wikistories#Running_locally
2. Replace `if ( frame.outdatedText ) {` with `if ( true ) {` in [[ https://github.com/wikimedia/mediawiki-extensions-Wikistories/blob/5907351fd2a971ab9839391bf93a3caf3766c5e5/resources/ext.wikistories.builder/store/story.js#L202 | line 202 of story.js ]]
3. Edit `MediaWiki:Wikistories-story-edittext-outdated` to `<img src="" onerror="alert('wikistories-story-edittext-outdated')">`
4. Go to `/wiki/Special:StoryBuilder/Main_Page`
5. Select any image
6. Click the blue ">" button
7. Click on the white text box at the bottom of the image
8. Select any text on the main page, for example "Community portal – The central hub for editors, with resources, links, tasks, and announcements."
9. Click "Add to story"
{F65677442}
### Cause
The message is retrieved through mw.msg(), implicitly using the text output mode:
https://github.com/wikimedia/mediawiki-extensions-Wikistories/blob/5907351fd2a971ab9839391bf93a3caf3766c5e5/resources/ext.wikistories.builder/store/story.js#L204
The message is then inserted as raw HTML using v-html:
https://github.com/wikimedia/mediawiki-extensions-Wikistories/blob/5907351fd2a971ab9839391bf93a3caf3766c5e5/resources/ext.wikistories.builder/components/StoryTextbox.vue#L22
## Additional information
* MediaWiki: 1.45.0-alpha (81259da)
* MinervaNeue: 1b253be
* EventLogging: 52ad027
* MobileFrontend: 6a82b62
* Wikistories: 5907351