Page MenuHomePhabricator

CVE-2026-22712: ApprovedRevs allows bypassing the inline CSS sanitizer due to magic word replacement in ParserAfterTidy
Closed, ResolvedPublicSecurity

Description

ApprovedRevs replaces the __APPROVEDREVS__ magic word in the ParserAfterTidy hook, allowing the inline CSS sanitizer to be bypassed.

Reproduction steps

  1. Go to /wiki/Special:ExpandTemplates?wpInput=%3Cpre%20style%3D%22background%3A%20u__APPROVEDREVS__rl%28%27%2F%2Fhttp.cat%2F418%27%29%22%2F%3E
  2. Observe that an HTTP request to https://http.cat/418 is sent because the CSS sanitizer was bypassed

image.png (600×642 px, 28 KB)

Cause

ApprovedRevs performs to magic word replacement in the ParserAfterTidy hook: https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/caf00bf928471fe6e30e8b1d7d3fea1de524e37f/includes/ApprovedRevsHooks.php#L956-L973
When this hook is run, strip markers are already unstripped. Because user-provided attribute values in elements inserted via strip markers (like the pre tag) are generally not safely encoded to escape underscores or other wikitext syntax, the __APPROVEDREVS__ magic word will be replaced in the style attribute of the <pre> element.

Additional information

  • MediaWiki: 1.46.0-alpha
  • Approved Revs: caf00bf

Event Timeline

SomeRandomDeveloper changed the task status from Open to Stalled.Dec 9 2025, 12:31 AM
SomeRandomDeveloper claimed this task.
This comment was removed by SomeRandomDeveloper.
SomeRandomDeveloper changed the task status from Stalled to Open.Dec 17 2025, 9:55 PM
SomeRandomDeveloper added a subscriber: Yaron_Koren.

(Reopening as this is no longer blocked)

@Yaron_Koren is there any specific reason the extension uses ParserAfterTidy here? Otherwise, I think an easy fix would be to just use InternalParseBeforeLinks instead

Wow, what a simple fix! No, there's no specific reason why it's using ParserAfterTidy - I'm guessing that I just copied that from another extension.

Patch:

Seems sane. I believe this can just be pushed through gerrit when you're ready. And then we'll likely re-announce it with T404620 if it's merged by early January 2026.

I plan to take care of this later today, unless anyone wants me to wait longer.

Change #1219656 had a related patch set uploaded (by Yaron Koren; author: Yaron Koren):

[mediawiki/extensions/ApprovedRevs@master] Change from ParserAfterTidy to InternalParseBeforeLinks hook

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

Change #1219656 merged by jenkins-bot:

[mediawiki/extensions/ApprovedRevs@master] Change from ParserAfterTidy to InternalParseBeforeLinks hook

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

Change #1224161 had a related patch set uploaded (by Mstyles; author: Yaron Koren):

[mediawiki/extensions/ApprovedRevs@REL1_45] Change from ParserAfterTidy to InternalParseBeforeLinks hook

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

Change #1224162 had a related patch set uploaded (by Mstyles; author: Yaron Koren):

[mediawiki/extensions/ApprovedRevs@REL1_44] Change from ParserAfterTidy to InternalParseBeforeLinks hook

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

Change #1224162 merged by jenkins-bot:

[mediawiki/extensions/ApprovedRevs@REL1_44] Change from ParserAfterTidy to InternalParseBeforeLinks hook

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

Change #1224161 merged by jenkins-bot:

[mediawiki/extensions/ApprovedRevs@REL1_45] Change from ParserAfterTidy to InternalParseBeforeLinks hook

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

Mstyles renamed this task from ApprovedRevs allows bypassing the inline CSS sanitizer due to magic word replacement in ParserAfterTidy to CVE-2026-22712: ApprovedRevs allows bypassing the inline CSS sanitizer due to magic word replacement in ParserAfterTidy.Jan 9 2026, 12:06 AM
Mstyles changed the visibility from "Custom Policy" to "Public (No Login Required)".
Mstyles changed the edit policy from "Custom Policy" to "All Users".