Information Disclosure

MEDIUM
facebook/react
Commit: 23fcd7cea1ec
Affected: Pre-19.2.4; specifically 19.2.0 through 19.2.3 (inclusive) for browser bundles; fixed in 19.2.4.
2026-04-17 20:22 UTC

Description

The commit changes production error handling for all browser bundles to minify prod error codes/messages, reducing information leakage. It also expands the error code map (scripts/error-codes/codes.json) and flips minifyWithProdErrorCodes from false to true for multiple bundles. The resulting behavior is that production browser errors no longer expose verbose internal messages or stack traces, mitigating potential information disclosure about internal server/client boundaries and bundler details.

Proof of Concept

PoC (conceptual): In a production build of a React app prior to this fix (e.g., 19.2.3), trigger a runtime error that originates from the server/client boundary (such as rendering a Server Component or invoking a server action). The browser console or error overlay may reveal verbose internal messages (module paths, server/client boundary notes, bundler details). After upgrading to 19.2.4 (where minifyWithProdErrorCodes is enabled for browser bundles), the same error would be sanitized to a generic message or code, with no exposed internal details. Example trigger (conceptual): - Server-side component throws new Error("Cannot find module \"../internal/secret\" in React Server Components"); - Client observes a production error in the console that lacks internal paths or sensitive details and shows only a sanitized error code/message. Note: This PoC is conceptual and assumes a server components setup in production. Actual reproduction requires a controlled environment with a pre-fix production build (19.2.3) and the post-fix build (19.2.4) for comparison.

Commit Details

Author: Sebastian "Sebbie" Silbermann

Date: 2026-04-17 16:01 UTC

Message:

Minify prod error messages for all browser bundles (#36277)

Triage Assessment

Vulnerability Type: Information Disclosure

Confidence: MEDIUM

Reasoning:

The change switches prod error messages to be minified in browser bundles, reducing the amount of potentially sensitive internal error details exposed to clients. This aligns with reducing information disclosure risk (information leakage) in production.

Verification Assessment

Vulnerability Type: Information Disclosure

Confidence: MEDIUM

Affected Versions: Pre-19.2.4; specifically 19.2.0 through 19.2.3 (inclusive) for browser bundles; fixed in 19.2.4.

Code Diff

diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index db92efc075c..345aa2b0aaf 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -568,5 +568,19 @@ "580": "Server Function has too many bound arguments. Received %s but the limit is %s.", "581": "BigInt is too large. Received %s digits but the limit is %s.", "582": "Referenced Blob is not a Blob.", - "583": "The current renderer does not support view transitions. This error is likely caused by a bug in React. Please file an issue." -} + "583": "The current renderer does not support view transitions. This error is likely caused by a bug in React. Please file an issue.", + "584": "Attempted to load a Server Reference outside the hosted root.", + "585": "Invalid server action: %s", + "586": "No server callback has been registered. Call setServerCallback to register one.", + "587": "Server actions must be functions", + "588": "Could not find the module \"%s\" in the React Server Consumer Manifest. This is probably a bug in the React Server Components bundler.", + "589": "Could not find the module \"%s\" in the React Server Manifest. This is probably a bug in the React Server Components bundler.", + "590": "Cannot await or return from a thenable. You cannot await a client module from a server component.", + "591": "Cannot access %s on the server. You cannot dot into a client module from a server component. You can only pass the imported name through.", + "592": "Cannot assign to a client module from a server module.", + "593": "Attempted to call the default export of %s from the server but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.", + "594": "Cannot read Symbol exports. Only named exports are supported on a client module imported on the server.", + "595": "Attempted to call %s() from the server but %s is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.", + "596": "Could not find the module \"%s\" in the React Client Manifest. This is probably a bug in the React Server Components bundler.", + "597": "The module \"%s\" is marked as an async ESM module but was loaded as a CJS proxy. This is probably a bug in the React Server Components bundler." +} \ No newline at end of file diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index 7b9508b9e29..25e5f31bf9e 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -415,7 +415,7 @@ const bundles = [ entry: 'react-dom/unstable_server-external-runtime', outputPath: 'unstable_server-external-runtime.js', global: 'ReactDOMServerExternalRuntime', - minifyWithProdErrorCodes: false, + minifyWithProdErrorCodes: true, wrapWithModuleBoundaries: false, externals: [], }, @@ -454,7 +454,7 @@ const bundles = [ name: 'react-server-dom-webpack-server.browser', condition: 'react-server', global: 'ReactServerDOMServer', - minifyWithProdErrorCodes: false, + minifyWithProdErrorCodes: true, wrapWithModuleBoundaries: false, externals: ['react', 'react-dom'], }, @@ -496,7 +496,7 @@ const bundles = [ 'react-server-dom-webpack/src/client/react-flight-dom-client.browser', name: 'react-server-dom-webpack-client.browser', global: 'ReactServerDOMClient', - minifyWithProdErrorCodes: false, + minifyWithProdErrorCodes: true, wrapWithModuleBoundaries: false, externals: ['react', 'react-dom'], }, @@ -566,7 +566,7 @@ const bundles = [ name: 'react-server-dom-turbopack-server.browser', condition: 'react-server', global: 'ReactServerDOMServer', - minifyWithProdErrorCodes: false, + minifyWithProdErrorCodes: true, wrapWithModuleBoundaries: false, externals: ['react', 'react-dom'], }, @@ -608,7 +608,7 @@ const bundles = [ 'react-server-dom-turbopack/src/client/react-flight-dom-client.browser', name: 'react-server-dom-turbopack-client.browser', global: 'ReactServerDOMClient', - minifyWithProdErrorCodes: false, + minifyWithProdErrorCodes: true, wrapWithModuleBoundaries: false, externals: ['react', 'react-dom'], }, @@ -641,7 +641,7 @@ const bundles = [ name: 'react-server-dom-parcel-server.browser', condition: 'react-server', global: 'ReactServerDOMServer', - minifyWithProdErrorCodes: false, + minifyWithProdErrorCodes: true, wrapWithModuleBoundaries: false, externals: ['react', 'react-dom'], }, @@ -682,7 +682,7 @@ const bundles = [ entry: 'react-server-dom-parcel/src/client/react-flight-dom-client.browser', name: 'react-server-dom-parcel-client.browser', global: 'ReactServerDOMClient', - minifyWithProdErrorCodes: false, + minifyWithProdErrorCodes: true, wrapWithModuleBoundaries: false, externals: ['react', 'react-dom'], }, @@ -731,7 +731,7 @@ const bundles = [ bundleTypes: [NODE_DEV, NODE_PROD, ESM_DEV, ESM_PROD], moduleType: RENDERER, entry: 'react-server-dom-esm/client.browser', - minifyWithProdErrorCodes: false, + minifyWithProdErrorCodes: true, wrapWithModuleBoundaries: false, externals: ['react', 'react-dom'], },
← Back to Alerts View on GitHub →