Why MCP and ChatGPT Apps Use Double Iframes

AI Engineergo watch the original →

ChatGPT and Claude use a double-iframe architecture to safely render third-party UI, preventing sandbox escapes while maintaining origin-indexed storage like localStorage and cookies.

The Double Iframe Architecture

To render third-party UI safely within a conversational agent, platforms like ChatGPT and Claude employ a nested iframe structure. A single-iframe approach using srcdoc fails because it inherits the parent host's Content Security Policy (CSP), which blocks third-party scripts. Relaxing the CSP to allow scripts creates a security vulnerability where the app can access the host's localStorage and cookies. Conversely, using a sandboxed iframe with allow-same-origin restores access to storage but effectively negates the sandbox, allowing the iframe to escape and access the parent DOM.

The double-iframe solution solves this by loading a lightweight, controlled script in an outer iframe hosted on a unique subdomain. This outer frame then loads the actual app HTML into an inner iframe using srcdoc. By assigning each app a unique subdomain, the platform prevents cross-app storage collisions while ensuring the app remains isolated from the host's sensitive data.

Developer Implications and Tooling

App developers must explicitly declare every external domain their view interacts with in the MCP app metadata. Failure to do so results in submission rejection, as the platform rewrites these domains into the nested iframe's CSP. Developers often struggle with these CSP configurations, which can lead to broken functionality in production that was not apparent during local development.

To mitigate these issues, the Skybridge framework provides a CSP inspector tool. This tool performs live diffing between the domains declared in the app metadata and the actual network calls made by the view. If a developer attempts to fetch data from an undeclared domain, the inspector flags the missing entry, allowing the developer to update the metadata before deployment.

  • #ai
  • #dev-tooling
  • #security

summary by google/gemini-3.1-flash-lite. probably wrong about something. check the source.