Applying Hardened Javascript to supply chain security for a proactive approach
Presenter: Zbyszek Tenerowicz
Position paper: Applying Hardened Javascript to supply chain security for a proactive approach
Slides: HTML | PDF
Video
Transcript
Zb: Hello! I'm Zb also known as naugtur. If you type naugtur into any text field and anything pops up that's likely gonna be about me. And I'm going to represent the project called LavaMoat. It's an open source tool; but I'm getting ahead of myself.
Zb: Let's start with a problem statement.
Zb: Early on, we had computers. And we would type programs into those computers and run these programs. And everything was fine.
Zb: And then we started having networks of computers. And we discovered that, hey? Someone's in my network, and I don't trust them.
Zb: What do I do about it. So we invented network security tools like firewalls.
Zb: and after that we have browsers, and we have multiple pages that could run in the same browser which, ended up in the same situation again. There's someone in my browser, and I don't trust them. So we invented same origin policy to prevent those situations.
Zb: Same origin policy. I heard it's debatable, but it's been quite successful, to date, to prevent sites interacting with each other in malicious ways, with very few exceptions. And then what happened next is we started composing software. We started composing software as multiple scripts being loaded from multiple sources onto the same page
Zb: and then also installing packages from Npm. And others and bundling them into one script that's running in the page. So we ended up in a similar situation again. There's someone in my code base, and I don't trust them.
Zb: And we invented hoping for the best. That's not entirely true. But pretty factual if you worked on projects that were building front end out of components from npm.
Zb: what we actually need here is called fearless cooperation, so that multiple parties can cooperate for the result of the same program without having to fear each other. So with enough isolation or security guarantees that they can interact without being maliciously interacted with.
Zb: The progress to date on the topic of handling situations where, within the same origin, we have multiple parties that need to somewhat be controlled starts with subresource integrity. We've got content security policy which can solve some of the issues that originate from using untrusted code in your page, in your origin, in your realm of the page. We've got Trusted Types that could potentially be used for that as well to some extent, and we've got hardened Javascript, which I'm going to talk about now.
Zb: Hardened Javascript, is a TD39 proposal. It's the brand name for the proposal. The actual proposal introduces a few things. One of them is module virtualization. So module loading, virtualization. So we can implement your own code for what happens when someone imports a module. And that would be part of the language. Another thing is evaluators where you can evaluate some code with the context that you provide, which means you decide, what is the global object which globals are available, and this exists as an implementation as SES shim and it's being used in LavaMoat, which is what brought me here in the first place. So what what is happening, and hopefully gets into Javascript, the language, soon enough, is that we have the possibility to isolate code from an untrusted party within the same realm. So within the same thread with the identity of global prototypes being the same. Under some circumstances which come from Javascript being hardened, these things can work together while being isolated.
Zb: So why am I still here talking about it? We have compartment in which we can isolate potentially malicious code, something we don't want to trust. What is the problem? First off, let's look at how it's even possible.
Zb: We're talking in the context of W3C, Javascript is standardized in Ecma. Add Conway's law, and you get good separation between the language itself and every powerful API in the language. So any power is only reachable through scope or imports and compartment controls those.
Zb: So what we do is we trickle in the selected globals into a compartment, and we can decide that a certain package in our dependencies will not have access to fetch, or any network whatsoever. and that works, that works already with the shim. By the way, there's 2 main issues to bring up here.
Zb: One of them is separate rounds. So spinning up a new same origin, window or frame is problematic, and that's what Gal is going to talk about. And also anything that gets access to a DOM node pretty much gets access to all the globals because of how the DOM API is structured, you can always go up until you reach the main document, and it's window. And there's a lot of window references and ways to get window reference in there.
Zb: So we're not done yet with the protections. Going back to problem statement, what I'm here to bring up is that, while TC39 is working on hardening Javascript, we could in parallel look into providing APIs or configurations or features that would let applications work in the browser without giving the software means to escape the compartment. Any access to DOM leaks globalThis, that's one of the problems.
Zb: Compartment depends on evaluators or bundling, so either you bundle the whole thing and create enough wrapping in there, or you have to have evaluators which are often banned by content security policy. So we should probably look into new directives and content security policy to allow selective use of evaluators for creating confinement in the page. So maybe strict-dynamic, but for eval. And then same origin realms. Not tomorrow. Today. In the next presentation.
Zb: The call to action here is: how can we support the users of Hardened Javascript in the browser so that they can maintain confinement while building UIs? Thank you.