Tags:


MetaMask JavaScript Security Stack (Part 3 - Snow) [๐•]

Originally posted on X

After covering LavaMoat ๐ŸŒ‹ scuttling #security feature and its fundamental issue of being unable to deny access to the "document" prop, which effectively eliminates its core concept, I implied we address that too with our in-house security tool.

#JavaScript folks? Meet Snow โ„๏ธ: An illustration of why Snow is important to ship LavaMoat security to child vulnerable realms (taken from https://weizmangal.com/2022/11/18/snow-into-metamask/)
Recap: What's scuttling?

Scuttling is a security feature in LavaMoat that removes all powerful capabilities from the global object so that if JS code escapes its LavaMoat sandbox to find more powerful APIs, it'll fail thanks to this feature making the global object useless:
Recap: What's scuttling's weak spot?

Problem is, not all props can be scuttled. One specifically ("document") can be used to form new global objects (e.g. with iframes) where the powerful APIs scuttling tries to deny can once again be found,

Making scuttling not very effective:
So what can we do about it?

Applying scuttling to all potential future global objects automatically, would restore the power of scuttling.

Because then, if attackers use "document" to create a new global object, scuttling would immediately be applied to that new object - magic! A lousy demonstration of how escaping the sandbox and then creating a child realm is not helpful for attackers when you can magically protect all new child realms that come to life in runtime
In other words:
1. scuttle main global object (=top)
2. intercept iframe creation
3. attacker creates iframe
4. scuttle iframe's global object at interception
5. return iframe to attacker

Result:
Attacker gets the iframe they formed, but its global object is also scuttled!

But, Step by step PoC demo of how recursive scuttling of realms would work
This is rather complicated because the browser doesn't offer us such power.

Meaning, we'd have to implement such a solution as a #JavaScript shim, where we map and (synchronously!) intercept all possible ways of forming new global objects.

Accomplishing that will allow us to...
... not only scuttle any newly created global object, but in general to run any arbitrary code for every time such an object is created - before the creator gets access to it.

That would restore the power of scuttling.

You see where I'm going with this, right?

Meet SNOW JS โ„๏ธ: Snow JS (tada)
Snow does just that!

By installing Snow in your webpage as first script, Snow intercepts (aka monkey patches) all methods of creating new realms.

Afterwards, by passing Snow a callback, Snow does its best in making sure to invoke that callback with every new realm creation. Showing how by passing Snow a callback, Snow invokes it for every new iframe that is created, regardless of how the iframe was formed
Building a bulletproof version of Snow is a long on-going mission that's yet to be completed, facing multiple complex obstacles along the way.

But with Snow, we're less concerned of "document" prop killing our scuttling idea - we just recursively scuttle child objects instead ๐Ÿ˜‰
Btw, if you're building similar security tools that apply JS runtime protection to web apps, you're probably affected by similar threats. You're welcome to reach out, ask about and also use Snow.
In the next ๐Ÿงต, I'll get more technical, exploring parts of Snow and its challenges.
In the meantime, some resources on Snow+scuttling:

* Integrating Snow into MetaMask ๐ŸฆŠ


* Snow on GitHub

* Live Demo of Snow (can you pop an alert?)

* Awesome Realms Security Repo