Safeguard
Security Guides•

Chat XSS in game clients and stream overlays: how to prevent it

Player names, chat lines and donation messages are untrusted input. Encode output by context, avoid innerHTML and add CSP as a backup layer.

Safeguard Security Team
3 min read

Chat messages, player names, clan tags and donation notes are text from strangers. If your web UI, launcher or stream overlay inserts them into a page as HTML, a crafted name can run script for every viewer. Prevent it by encoding output for its context, using safe DOM methods, and treating a content security policy as a backup.

Where this shows up

Modern games and creator tools use web technology in many places: in game browsers, launchers, store pages, leaderboards, moderation consoles and stream overlays that display chat or alerts. The risk is high on overlays and moderator tools, because they often run in privileged contexts and show messages from the public.

The core rules from OWASP

The OWASP Cross Site Scripting Prevention Cheat Sheet boils it down to a few rules.

Encode output for the place it lands. Start with your framework's automatic escaping. For HTML body text use HTML entity encoding. For attributes, quote the value and use attribute encoding. For JavaScript contexts use an encoder built for that purpose, because hand escaping quotes is not enough. For URLs, percent encode parameter values.

Prefer safe DOM sinks. Use textContent or insertAdjacentText instead of innerHTML when you place user text on the page.

Sanitize when users must send HTML. If a feature, such as rich profile text, truly needs markup, use a maintained sanitizer, do not modify the output afterwards, and keep the library patched.

Avoid dangerous placements. Do not put user data inside script blocks, comments, event handler strings or calls like eval.

Add a CSP as a backup. A content security policy supplements the above and does not replace it. OWASP also notes that filters, interceptors and WAFs are not reliable substitutes.

Game specific traps

  • Name changes. Names appear in many places, such as chat, scoreboards, kill feeds and emails. Encode them everywhere, not only where you first noticed the bug.
  • Markup features. Colour codes, emotes and mentions are often implemented by string replacement. Make sure the replacement runs on already encoded text, not before encoding.
  • Overlays. An overlay that renders alerts from a third party service is trusting that service. Treat inbound alert text as untrusted.
  • Moderation tools. Staff tools see the worst input. A stored script in a report queue can steal a moderator session, so test these panels first.
  • Voice to text and translated chat. Output from another service is still untrusted text.

A practical test

Create a test account whose name contains common script and attribute breaking characters, then walk through every screen that shows it. Do the same with chat, clan names, bios and report reasons. Fix what breaks at the output point rather than by banning characters, since filters tend to leave gaps.

Checklist

  1. Find every place user text reaches HTML.
  2. Switch those places to auto escaped templates or textContent.
  3. Review all uses of innerHTML and similar sinks.
  4. Add a CSP and monitor reports.
  5. Keep UI libraries patched.

Safeguard's dependency scanning can flag vulnerable UI and sanitizer library versions in your web projects. Free scan: https://gold.safeguard.sh/scan.

Quick check

Can I just block angle brackets in names?

That helps little. Encode output for each context and use safe DOM methods. Input filters leave gaps and break legitimate names.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.