LavaMoat / snow

Use Snow to finally secure your web app's same origin realms!
https://lavamoat.github.io/snow/demo/
MIT License
102 stars 9 forks source link

Bypass using nested iframe #93

Closed mmndaniel closed 1 year ago

mmndaniel commented 1 year ago
var d = document.createElement('div');
document.body.appendChild(d);
d.innerHTML = `
<iframe srcdoc="<iframe></iframe><script>frames[0].alert(1)</script>">
</iframe>`;

No src, srcdoc, attributes, listeners, etc... so it's just left unhooked.

weizman commented 1 year ago

This is a cool one actually. It was a conscious decision in Snow to not attempt to protect the initial HTML from same origin realms, but only JS created same origin realms (hard to explain why, mostly because it's usually out of Snow's power to attempt to accomplish that in the first place). However, Snow not taking that into consideration, allows achieving that state with the "initial" HTML of a child frame rather the top. And that is something Snow should take care of.

weizman commented 1 year ago

in other words, a simpler version of your PoC works too:

var d = document.createElement('iframe');
d.srcdoc = `<iframe></iframe><script>frames[0].alert(1)</script>`;
document.body.appendChild(d);
weizman commented 1 year ago

Ok I came up with a draft for the solution but I'm not sure how I feel about it.. #101

In such scenarios (new inner documents such as srcdoc), I am handling dynamic creation of iframes. What I'm not handling, as described above, is specifically static iframes (iframes that appear in the HTML of the srcdoc itself).

So in #101 I created some code that when srcdoc is called, goes through all frames that are being injected and injects a script tag right afterwards that will take the upper frame and pass it to snow - something like this:

// before
<iframe></iframe>
<script>frames[0].alert(1)</script>
// after
<iframe></iframe>
<script>
    * find iframe above
    * pass it to snow
    * remove this script
</script>
<script>frames[0].alert(1)</script>

This still can be bypassed based on previous, yet to be addressed, issues such as #92 / #90 / etc, which hopefully should be addressed separately.

I hope this solution is hermetic but I feel like I'm too deep into defense here.. would love some help on this @mmndaniel

weizman commented 1 year ago

There might be so many edge cases to trying to parse this HTML and patch it up... might require some more research..