When using the RelatedArticles extension along with TextExtracts or WikiBase as the description source, arbitrary HTML and JS can be inserted into the DOM.
## TextExtracts as the description source
### Reproduction steps
* Enable the RelatedArticles extension
* Add `$wgRelatedArticlesDescriptionSource = 'textextracts';` to your LocalSettings.php
* Create a page called `RelatedArticlesXSS` and insert `<img src="" onerror="alert(1)">` into it
* Create a page called `RelatedArticlesXSS2` and insert `{{#related:RelatedArticlesXSS}}` into it
* Visit RelatedArticlesXSS2
{F62276405}
### Cause
# The `extracts` prop for the `RelatedArticlesXSS` page is queried via the API: https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/RelatedPagesGateway.js#L72-L102
# The API result is returned by `getForCurrentPage`: https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/RelatedPagesGateway.js#L155
# The `pages` object of the query result is passed to the `render` function: https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/index.js#L75-L89
# The innerHtml of the RelatedArticles container is set to the result of the `RelatedArticles` function, while passing the result of getCards (which doesn't escape any of the query results, but just assigns them to an object): https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/index.js#L55-L60
# Finally, the description is inserted as raw HTML: https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/RelatedArticles.js#L30
## Wikibase as the description source
### Reproduction steps
* Enable the RelatedArticles extension
* Add `$wgRelatedArticlesDescriptionSource = 'wikidata';` to your LocalSettings.php
* Have an item with a description like `<img src="" onerror="alert(1)">` (note: `<script>alert(1)</script>` won’t do, the script gets injected into the DOM but not executed)
* Connect a wiki page to it via sitelink
* Declare that wiki page as a related article
### Cause
# The `description` prop for the page is queried via the API: https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/RelatedPagesGateway.js#L72-L102
# The API result is returned by `getForCurrentPage`: https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/RelatedPagesGateway.js#L155
# The `pages` object of the query result is passed to the `render` function: https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/index.js#L75-L89
# The innerHtml of the RelatedArticles container is set to the result of the `RelatedArticles` function, while passing the result of getCards (which doesn't escape any of the query results, but just assigns them to an object): https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/index.js#L55-L60
# Finally, the description is inserted as raw HTML: https://github.com/wikimedia/mediawiki-extensions-RelatedArticles/blob/169e76305cbc9dc6a66f43c4116afaa42e39dcd7/resources/ext.relatedArticles.readMore/RelatedArticles.js#L30
## Additional information
MediaWiki: 1.45.0-alpha (b6993c3)
PHP: 8.3.14 (fpm-fcgi)
RelatedArticles: 3.1.0 (169e763)
TextExtracts: 4ba1f5c
Browser: Firefox 139.0 on Fedora Linux 42