Skip to content

SLOP-396/SLOP-382: harden forceGraph JSON encoding; replace removed wfMsgHTML - #2

Open
tosfos wants to merge 1 commit into
masterfrom
SLOP-396-xss-forcegraph-wfmsghtml
Open

SLOP-396/SLOP-382: harden forceGraph JSON encoding; replace removed wfMsgHTML#2
tosfos wants to merge 1 commit into
masterfrom
SLOP-396-xss-forcegraph-wfmsghtml

Conversation

@tosfos

@tosfos tosfos commented Aug 23, 2026

Copy link
Copy Markdown

Summary

Two fixes in specials/SpecialWatchAnalytics.php:

  1. SLOP-396 — forceGraph JSON encoding: the graph blob (containing usernames and page titles — attacker-influenceable stored data) is embedded in <script type='text/template'> via plain json_encode(). Encoding now uses JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT so <, >, &, quotes are hex-escaped and the block cannot be terminated or polluted by payload content, independent of PHP build defaults. Client-side JSON.parse() decodes the escapes transparently (verified round-trip), so rendering is unchanged for benign data.
  2. SLOP-382 — wfMsgHTML() removed in MW 1.27: wfMsgHTML( 'listusers-noresult' ) fatals on any modern MW when the user list is empty. Replaced with $this->msg( 'listusers-noresult' )->escaped() — byte-identical semantics (htmlspecialchars).

Verification

  • php -l clean on php:7.4-cli and php:8.2-cli.
  • Harness on both 7.4 and 8.2: NEW encoding output contains no raw </>; payload round-trips byte-identical through json_decode; ->escaped() matches old wfMsgHTML semantics.
  • Note: modern PHP (7.4+/8.x) escapes / in json_encode by default, which already mitigates the plain </script> case; the explicit flags make the guarantee unconditional and also neutralize raw </> from any source.

Closes SLOP-396, SLOP-382.

…fMsgHTML

Special:WatchAnalytics::forceGraph() now encodes the graph JSON with
JSON_HEX_TAG|AMP|APOS|QUOT so usernames/titles embedded in the
text/template script block cannot break out into markup regardless of
runtime defaults; JSON.parse on the client decodes transparently.

wfMsgHTML() (removed in MW 1.27) replaced with ->escaped(), identical
semantics.
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 22d2d823-b215-4304-8c51-e9d0092f8c60


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant