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 trusted HTML type confusion #95

Closed mmndaniel closed 1 year ago

mmndaniel commented 1 year ago
var d = document.createElement('div')
d.innerHTML = '<iframe id="f"></iframe>';
var f = d.firstChild;
d.toJSON = ()=>'asd';
f.toJSON = ()=>'asd';
document.documentElement.toJSON = ()=>'asd';
document.body.appendChild(d);
f.contentWindow.alert(1);

Essentially exploiting two things: a. JSON.stringify bevavior can be overridden with toJSON method (see MDN) b. This line excludes trusted HTMLs (perhaps because it assumes it was already handled by handleHTML?) by evaluating: typeof parse(stringify(node, replacer)) === 'string', which can be made to return true by utilizing a.

weizman commented 1 year ago

Great lead on this one. This happened for 2 unprofessional reasons on my end:

  1. It was written a while ago, back when I wasn't really aware of what trusted types were. I just stumbled upon this when I injected Snow into YouTube and these trusted types crashed Snow for not being actual nodes. I needed to find a safe way to tell them apart from nodes to skip them when trying to protect node insertions. I ended up finding the JSON.stringify trick where its result is a string for trusted types but an object for actual nodes - which brings me to the next point:
  2. I was also not aware of toJSON really.

To fix this I had to find a way to tell trusted HTMLs apart from nodes in a safer way, for that I came up with #102

weizman commented 1 year ago

fixed #102

mmndaniel commented 1 year ago

Wouldn't it be easier to use this?