Skip to content

sandbox.permissions prop is not respected - hardcoded in setupSandboxProxyIframe #184

@kvtemadden

Description

@kvtemadden

I'm using AppRenderer to display pre-fetched HTML from an MCP server. I route all MCP communication through a backend proxy (for authentication), so the frontend only receives the final HTML to render.

I wanted to use the sandbox.permissions prop to set stricter sandbox permissions ("allow-scripts" only), but it appears the prop is being ignored.

Current behaviour

When passing:

<AppRenderer
  sandbox={{ 
    url: sandboxUrl, 
    permissions: "allow-scripts"  // ❌ Ignored
  }}
  html={htmlContent}
  ...
/>

The resulting iframe still has:

<iframe sandbox="allow-scripts allow-same-origin allow-forms" ...>

Suspected culprit

The permissions prop is defined in the SandboxConfig TypeScript interface, but it's never passed to or used by the setupSandboxProxyIframe function in src/utils/app-host-utils.ts:

// src/utils/app-host-utils.ts (around line 50)
export function setupSandboxProxyIframe(url: URL) {
  const iframe = document.createElement('iframe');
  // ... styling ...
  iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');

The function signature doesn't accept a permissions parameter, and AppFrame.tsx doesn't pass it when calling this function.

The current behaviour prevents removing allow-same-origin, which triggers a browser security warning:

⚠️ An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing

Question

I noticed this PR added the permissions type definition. Was this intended for a different purpose, or is this a bug where the implementation wasn't completed?

Is there a reason the hardcoded permissions can't be made configurable via the existing sandbox prop?

Version

  • @mcp-ui/client: v6.1.0

Workaround

Currently using a MutationObserver to override the attribute after the iframe is created, but this is hacky and has a potential race condition window.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions