Skip to content

fix(shared): wrap addObjectToProperties in try-catch to handle cross-origin SecurityError#36451

Open
sleitor wants to merge 1 commit into
facebook:mainfrom
sleitor:fix-36430
Open

fix(shared): wrap addObjectToProperties in try-catch to handle cross-origin SecurityError#36451
sleitor wants to merge 1 commit into
facebook:mainfrom
sleitor:fix-36430

Conversation

@sleitor
Copy link
Copy Markdown
Contributor

@sleitor sleitor commented May 11, 2026

Summary

In React 19.2 DEV builds, logComponentRender (called from commitPassiveMountOnFiber) calls addObjectToProperties which performs an unguarded for...in over every prop value. When a component receives a cross-origin Window object (e.g. iframe.contentWindow with srcdoc="" / null origin) as a prop, the enumeration throws SecurityError in browsers that enforce the same-origin policy.

This SecurityError propagates out of the commit phase and leaves the work-in-progress fiber broken, causing all subsequent renders to throw Should not already be working. and making the UI completely unresponsive.

Root Cause

addObjectToProperties in packages/shared/ReactPerformanceTrackProperties.js runs for (const key in object) without any error guard. For a cross-origin Window (null origin iframe), browsers block property enumeration and throw SecurityError. Since this error is not caught, it escapes the commit phase and corrupts the fiber tree.

Similarly, readReactElementTypeof accesses '2796107typeof' in value without a guard, which can also throw for cross-origin objects.

Fix

  • Wrap the for...in loop in addObjectToProperties with try-catch. On SecurityError, show [CrossOriginObject] as a placeholder so the render-logger degrades gracefully without corrupting the fiber.
  • Wrap the in / hasOwnProperty checks in readReactElementTypeof with try-catch so $$typeof access never escapes either.

Both are DEV-only diagnostic paths and must not affect production builds or corrupt fiber state when iterating untrusted props.

Test

Added a new test in ReactPerformanceTrack-test.js that simulates a cross-origin Window via a Proxy whose ownKeys and getOwnPropertyDescriptor traps throw, verifying that:

  1. The render completes without throwing
  2. Subsequent renders succeed (fiber tree not corrupted)

Fixes #36430

…origin SecurityError

In React 19.2 DEV builds, logComponentRender (called from
commitPassiveMountOnFiber) calls addObjectToProperties which performs
an unguarded 'for...in' over every prop value. When a component
receives a cross-origin Window object (e.g. iframe.contentWindow with
srcdoc='' / null origin) as a prop, the enumeration throws
SecurityError in browsers that enforce the same-origin policy.

This SecurityError propagates out of the commit phase and leaves the
work-in-progress fiber broken, causing all subsequent renders to
throw 'Should not already be working.' and making the UI completely
unresponsive.

Fix:
- Wrap the 'for...in' loop in addObjectToProperties with try-catch.
  On SecurityError, show '[CrossOriginObject]' as a placeholder so
  the render-logger degrades gracefully without corrupting the fiber.
- Wrap the 'in' / hasOwnProperty checks in readReactElementTypeof
  with try-catch so 2795888typeof access never escapes either.

Both are DEV-only diagnostic paths and must not affect production
builds or corrupt fiber state when iterating untrusted props.

Repro: pass iframe.contentWindow (srcdoc iframe, null origin) as a
prop to any component in a DEV Vite+React 19.2 app.

Fixes facebook#36430
@meta-cla meta-cla Bot added the CLA Signed label May 11, 2026
@react-sizebot
Copy link
Copy Markdown

Comparing: d5736f0...d445a88

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB = 1.88 kB 1.88 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 613.53 kB 613.53 kB = 108.44 kB 108.44 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB +0.05% 1.88 kB 1.88 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 679.46 kB 679.46 kB = 119.40 kB 119.40 kB
facebook-www/ReactDOM-prod.classic.js = 699.88 kB 699.88 kB = 122.96 kB 122.96 kB
facebook-www/ReactDOM-prod.modern.js = 690.20 kB 690.20 kB = 121.35 kB 121.35 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable-semver/react-client/cjs/react-client-flight.development.js +0.41% 182.58 kB 183.33 kB +0.25% 31.67 kB 31.75 kB
oss-stable/react-client/cjs/react-client-flight.development.js +0.41% 182.61 kB 183.36 kB +0.25% 31.69 kB 31.77 kB
oss-experimental/react-client/cjs/react-client-flight.development.js +0.41% 182.61 kB 183.36 kB +0.25% 31.69 kB 31.77 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.development.js +0.40% 188.33 kB 189.08 kB +0.25% 33.01 kB 33.10 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.development.js +0.40% 188.38 kB 189.13 kB +0.25% 33.04 kB 33.12 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.development.js +0.40% 188.39 kB 189.14 kB +0.25% 33.04 kB 33.13 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.development.js +0.40% 188.94 kB 189.68 kB +0.20% 33.40 kB 33.47 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.development.js +0.40% 188.94 kB 189.68 kB +0.20% 33.40 kB 33.47 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.development.js +0.40% 188.94 kB 189.68 kB +0.20% 33.40 kB 33.47 kB
facebook-www/ReactFlightClient-dev.modern.js +0.39% 189.48 kB 190.23 kB +0.24% 33.45 kB 33.52 kB
facebook-www/ReactFlightClient-dev.classic.js +0.39% 189.49 kB 190.23 kB +0.24% 33.45 kB 33.52 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.39% 190.36 kB 191.11 kB +0.22% 33.43 kB 33.50 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.39% 190.41 kB 191.16 kB +0.22% 33.46 kB 33.53 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.39% 190.42 kB 191.17 kB +0.23% 33.46 kB 33.54 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.39% 192.28 kB 193.03 kB +0.20% 33.93 kB 34.00 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.39% 192.28 kB 193.03 kB +0.20% 33.93 kB 34.00 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.39% 192.28 kB 193.03 kB +0.20% 33.93 kB 34.00 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.39% 192.31 kB 193.05 kB +0.22% 33.94 kB 34.02 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.39% 192.31 kB 193.05 kB +0.22% 33.94 kB 34.02 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.39% 192.31 kB 193.05 kB +0.22% 33.94 kB 34.02 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.39% 192.93 kB 193.67 kB +0.24% 33.90 kB 33.99 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.39% 192.98 kB 193.72 kB +0.24% 33.93 kB 34.01 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.39% 192.99 kB 193.74 kB +0.24% 33.93 kB 34.02 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.39% 193.55 kB 194.30 kB +0.26% 34.08 kB 34.17 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.39% 193.60 kB 194.35 kB +0.25% 34.11 kB 34.19 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.39% 193.61 kB 194.36 kB +0.25% 34.11 kB 34.20 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.39% 193.73 kB 194.47 kB +0.22% 34.11 kB 34.18 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.39% 193.73 kB 194.47 kB +0.22% 34.11 kB 34.18 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.39% 193.73 kB 194.47 kB +0.22% 34.11 kB 34.18 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.development.js +0.38% 195.73 kB 196.48 kB +0.20% 34.23 kB 34.30 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.development.js +0.38% 195.73 kB 196.48 kB +0.20% 34.23 kB 34.30 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.development.js +0.38% 195.73 kB 196.48 kB +0.20% 34.23 kB 34.30 kB
oss-experimental/react-server-dom-unbundled/cjs/react-server-dom-unbundled-client.node.development.js +0.38% 197.38 kB 198.13 kB +0.21% 34.47 kB 34.55 kB
oss-stable-semver/react-server-dom-unbundled/cjs/react-server-dom-unbundled-client.node.development.js +0.38% 197.38 kB 198.13 kB +0.21% 34.47 kB 34.55 kB
oss-stable/react-server-dom-unbundled/cjs/react-server-dom-unbundled-client.node.development.js +0.38% 197.38 kB 198.13 kB +0.21% 34.47 kB 34.55 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.38% 198.78 kB 199.53 kB +0.21% 34.74 kB 34.81 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.38% 198.78 kB 199.53 kB +0.21% 34.74 kB 34.81 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.38% 198.78 kB 199.53 kB +0.21% 34.74 kB 34.81 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.38% 198.80 kB 199.55 kB +0.20% 34.76 kB 34.83 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.38% 198.80 kB 199.55 kB +0.20% 34.76 kB 34.83 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.38% 198.80 kB 199.55 kB +0.20% 34.76 kB 34.83 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.25% 238.87 kB 239.48 kB +0.30% 53.17 kB 53.32 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.25% 238.90 kB 239.50 kB +0.30% 53.19 kB 53.35 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.25% 238.90 kB 239.51 kB +0.30% 53.20 kB 53.35 kB

Generated by 🚫 dangerJS against d445a88

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: [19.2] DEV-build logComponentRender throws SecurityError on cross-origin Window props

2 participants