-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Snow can be bypassed by creating a Blob URI inside a worker #158
Comments
Hi @matanber, As you've probably seen, there are quite a few reported issues against the Snow project, which we haven't addressed yet on purpose. These issues have taught us that browsers are just too unable to help us address this issue in the user land (meaning by implementing JS rules at runtime). By "this issue" I refer to the ability to form new same origin realms and access them even when an app wants to forbid it. This is also known as the same origin concern which we write about a lot and are trying to convince browser vendors to help defend against this problem natively (see our explainer). I'm telling you this because I don't want you to spend some of your precious time on Snow until we either address these issues or decide to form a different version of a solution to this problem (WIP). I take responsibility for not making this clear in the README file, I will make sure to do so. I at least hope this was fun for you and helped you comprehend this new type of problem we're trying to defend and address - with hope to succeed one day! Either way, thanks for the effort, it is much appreciated. (p.s. have a go at LavaDome - I think is has a better shot at succeeding than Snow, at least for now) |
And as for this bypass specifically - awesome work. Truly. |
function swap2(aURL) {
const url = typeof aURL === 'string' ? aURL : toString(aURL);
if (stringStartsWith(url, 'blob')) {
if (!blobs.has(url)) {
const content = syncGet(url);
const preloadURL = createObjectURL(new Blob([`window.parent.SNOW_WINDOW(window);`], {
type: 'text/javascript'
}));
const prefix = `<script src=${preloadURL}></script>`;
const js = prefix + '\n\n' + content;
blobs.set(url, createObjectURL(new Blob([js], {
type: 'text/html'
})));
}
return blobs.get(url);
}
return url;
}
Object.defineProperty(win.HTMLIFrameElement.prototype, 'src', {
configurable: true,
enumerable: true,
set: function(url) {
return setSrc(this, "IFRAME", swap2(url));
}
});
Object.defineProperty(win.HTMLFrameElement.prototype, 'src', {
configurable: true,
enumerable: true,
set: function(url) {
return setSrc(this, "FRAME", swap2(url));
}
});
function setSrc(element, tag, url) {
switch (tag) {
case 'IFRAME':
return bag.iframeSrc.call(element, url);
case 'FRAME':
return bag.frameSrc.call(element, url);
default:
return null;
}
} The code above is a solution to the problem,, but I only tested the code in the |
|
I got confused because |
It's all a matter of what you're trying to defend 😉 |
It is possible to provide some protections against this bypass without Realm Initialization Control, although RIC would make it much easier to solve. |
In order to prevent Blob URIs from being created within workers, snow overrides the
Worker
constructor using the following code:This code overrides the
URL.createObjectURL
function in every worker that is created from a URL that begins with 'blob'. Because URI schemes are case-insensitive, this can be bypassed simply by creating a worker with a URL that begins with 'Blob'. Here is a little demo for that:Building on top of arxenix's brilliant bypass in issue #43, this can be used to bypass Snow using the following PoC:
The text was updated successfully, but these errors were encountered: