polcak / jsrestrictor

JavaScript Restrictor web extension
GNU General Public License v3.0
249 stars 29 forks source link

iframes bypass HTMLElement restrictions (currently canvas) #34

Closed raszpl closed 4 years ago

raszpl commented 4 years ago

https://browserleaks.com/canvas

<iframe id="canvas_iframe" sandbox="allow-same-origin"></iframe>
c = document.getElementById("canvas_iframe").contentDocument.createElement("canvas");
c.getContext("2d")
console.log(c.toDataURL);

will bypass toDataURL stub and return [native code]

you need something like this:

function c(a){
a.HTMLCanvasElement.prototype.toDataURL = function() { return "" };
a.HTMLCanvasElement.prototype.toBlob = function() { return "" };
a.HTMLCanvasElement.prototype.getImageData = function() { return "" };
a.CanvasRenderingContext2D.prototype.toDataURL = function() { return "" };
a.CanvasRenderingContext2D.prototype.toBlob = function() { return "" };
a.CanvasRenderingContext2D.prototype.getImageData = function() { return "" };
}

c(window);
var g=HTMLIFrameElement.prototype.__lookupGetter__('contentWindow'),
    h=HTMLIFrameElement.prototype.__lookupGetter__('contentDocument');

Object.defineProperties(HTMLIFrameElement.prototype,{contentWindow:{get:function(){var a=g.call(this);
try{a.HTMLCanvasElement}catch(d){return console.log('HTMLIFrameElement.contentWindow properties could not be accessed anyway: %o',d),a}
c(a);return a}},contentDocument:{get:function(){var a=g.call(this);
try{a.HTMLCanvasElement}catch(d){return console.log('HTMLIFrameElement.contentWindow properties could not be accessed anyway: %o',d),a}
c(a);
return h.call(this)}}})

to wrap canvases inside same origin iframes. Not my code. Found it some time ago but didnt understand the purpose at first, finally https://browserleaks.com/canvas iframe trick made everything clear. Patches contentDocument contentWindow accesses to hotpatch HTMLCanvasElement/CanvasRenderingContext2D inside of accessed iframes.

polcak commented 4 years ago

Also valid for the rewrite branch.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox#attr-sandbox: allow-same-origin: If this token is not used, the resource is treated as being from a special origin that always fails the same-origin policy.

Thanks for the link.

polcak commented 4 years ago

POC page https://www.fit.vutbr.cz/~ipolcak/jsr/iframe/iframe.php shows that the problem concerns all iframes.

Also the problem should affect all HTML elements. Currently, we wrap canvas element only.

polcak commented 4 years ago

Fixed in ea02f05 (except #25). @raszpl Thank you for reporting and providing the code.