Skip to content

Fix stored XSS via BBCode attribute injection#58

Open
az10b wants to merge 1 commit intom1k1o:masterfrom
az10b:fix/xss-bbcode-attribute-injection
Open

Fix stored XSS via BBCode attribute injection#58
az10b wants to merge 1 commit intom1k1o:masterfrom
az10b:fix/xss-bbcode-attribute-injection

Conversation

@az10b
Copy link
Copy Markdown

@az10b az10b commented Apr 9, 2026

Summary

  • BBCode option values (e.g. [goal=OPTION], [code=OPTION], [img=OPTION]) were inserted into HTML templates without escaping
  • A malformed option like [goal=x" onclick="alert(1)] triggers a ParserException fallback in the option parser that preserves raw quotes, allowing HTML attribute breakout and arbitrary event handler injection
  • Applied htmlspecialchars(ENT_QUOTES, UTF-8) to all option values before HTML substitution in CodeDefinition::asHtml(), and to the custom [code] tag's class attribute in Post::parse_content()

Affected tags

Tag Template Vulnerable param
[goal=OPT] <div class="b_goal {option}"> {option} — no validator
[code=OPT] <code class="OPT"> custom asHtml — no escaping
[img=OPT] <img alt="{option}"> {option} — no validator

Test plan

  • Post [goal=x" onclick="alert(1)]test[/goal] — verify alert does NOT fire on click
  • Post [code=x" onmouseover="alert(1)]test[/code] — verify alert does NOT fire on hover
  • Post [img=x" onerror="alert(1)]https://example.com/img.jpg[/img] — verify alert does NOT fire
  • Post [goal=star]test[/goal] — verify normal usage still works
  • Post [code=php]echo "hi";[/code] — verify code highlighting still works

🤖 Generated with Claude Code

BBCode option values were substituted into HTML templates without
escaping. A malformed option like [goal=x" onclick="alert(1)]
triggered a ParserException fallback that preserved raw quotes,
allowing attribute breakout and arbitrary event handler injection.

Apply htmlspecialchars(ENT_QUOTES, UTF-8) to all option values
before HTML substitution in CodeDefinition::asHtml(), and to the
custom [code] tag's class attribute in Post::parse_content().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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