@@ -73,7 +73,8 @@ const PROXY_READY_NOTIFICATION: McpUiSandboxProxyReadyNotification["method"] =
7373
7474window . addEventListener ( "message" , async ( event ) => {
7575 if ( event . source === window . parent ) {
76- if ( event . origin !== EXPECTED_HOST_ORIGIN ) {
76+ const normalizeOrigin = ( origin : string ) => origin . replace ( "://127.0.0.1" , "://localhost" ) ;
77+ if ( normalizeOrigin ( event . origin ) !== normalizeOrigin ( EXPECTED_HOST_ORIGIN ) ) {
7778 console . error (
7879 "[Sandbox] Rejecting message from unexpected origin:" ,
7980 event . origin ,
@@ -95,34 +96,32 @@ window.addEventListener("message", async (event) => {
9596 if ( typeof html === "string" ) {
9697 const sendInit = ( ) => {
9798 if ( inner . contentWindow ) {
98- inner . contentWindow . postMessage ( { type : "sandbox-init" } , OWN_ORIGIN ) ;
99+ // Use "*" because sandboxed iframes with no 'allow-same-origin' have a "null" origin.
100+ // A specific target origin will fail matching and block delivery.
101+ inner . contentWindow . postMessage ( { type : "sandbox-init" } , "*" ) ;
99102 }
100103 } ;
101104 inner . onload = sendInit ;
102105
103- const doc = inner . contentDocument || inner . contentWindow ?. document ;
104- if ( doc ) {
105- doc . open ( ) ;
106- doc . write ( html ) ;
107- doc . close ( ) ;
108- // doc.write doesn't always trigger iframe onload reliably.
109- Promise . resolve ( ) . then ( sendInit ) ;
110- } else {
111- inner . srcdoc = html ;
112- }
106+ inner . srcdoc = html ;
113107 }
114108 } else {
115109 if ( inner && inner . contentWindow ) {
116- inner . contentWindow . postMessage ( event . data , OWN_ORIGIN ) ;
110+ // Same rationale as above: target origin must be "*" to reach sandboxed 'null' windows.
111+ inner . contentWindow . postMessage ( event . data , "*" ) ;
117112 }
118113 }
119114 } else if ( event . source === inner . contentWindow ) {
120- if ( event . origin !== OWN_ORIGIN ) {
115+ // MUST allow the string "null" as the origin. Without 'allow-same-origin',
116+ // browsers force sandboxed frames to an anonymous, unique origin that serializes to "null".
117+ // Security verification relies primarily on ensuring 'event.source === inner.contentWindow'.
118+ if ( event . origin !== OWN_ORIGIN && event . origin !== "null" ) {
121119 console . error (
122120 "[Sandbox] Rejecting message from inner iframe with unexpected origin:" ,
123121 event . origin ,
124122 "expected:" ,
125- OWN_ORIGIN
123+ OWN_ORIGIN ,
124+ "or null"
126125 ) ;
127126 return ;
128127 }
0 commit comments