Is it wise to run code from strangers? Well, we do it all the time and there's no backing out of it. Let's take a look at how a JavaScript project could get hacked and then defend itself from supply chain attacks. Limit access to globals for each package? Sure. Control if a package can access network or file system? Yup, that too. And no more install scripts or prototype pollution.
I Run Code From the Internet!

AI Generated Video Summary
Today's Talk covers the risks of running someone else's code, the use of supply chain security tools, and the automation of package analysis with SocketDev. It also introduces the concept of Hardened JavaScript and Lockdown for creating secure environments. The mention of LavaMode and its bundler, as well as the application example using Cookiemonster, showcases the practical applications of these tools. The speaker also offers assistance in implementing Lavamote for projects.
1. Running Someone Else's Code and Ensuring Security
Today, we're going to look at running someone else's code and the potential risks associated with it. NPM packages, although widely used, can pose a threat as they are unsanitized input from the internet. Supply chain security tools can help identify malicious packages, but they are not foolproof. SocketDev automates the process of finding suspicious qualities in packages, providing a better feedback loop. At Lavamote, we take a proactive approach by assuming that one of the dependencies is already malicious. LavaMode allows you to generate a policy for your application and run it based on that policy, isolating each dependency using Hardened JavaScript.
Hello everyone! I'm Nauchter, you can find me online if you type Nauchter anyway, nauchter.pl Nauchter.pl is my website, it has a bunch of other material on JavaScript, security and other things.
And today, we're going to look at running someone else's code. Speaking of that, if I gave you a string of text and asked you to put it in your application and run it, would you do that? Would you put my code in production without looking at it much? Well, I guess the answer is going to be no. But would it help if I put it in a tar.gz file? Is it more appealing that way? Somehow it is, because that's what NPM packages are. And they're great, and everyone's using them, but they're actually unsanitized input from the internet, that we put in our applications and run. Okay? So yes, that's what we're doing, we're doing that all the time. I'm installing NPM packages all the time. What if some of the packages in there aren't great? And by that, I don't mean lousy packages. I published some lousy packages, and nothing bad happened. But I mean malicious packages, dangerous packages, that want to hurt your application, your users. What do we do about that? Well, there's tools for supply chain security, right? So, a tool might say, hey, some researchers found out that this package is not great, and they reported it. So, that package that you shipped to production a few weeks ago, now we know that it's not a good one. Please do something about it. Is that a great situation to be in? Not necessarily. Okay, there's SocketDev. You can use that and get a much better feedback loop, because SocketDev is automating finding suspicious qualities about packages. So, SocketDev, within a few hours of the package being published, is going to be able to tell you that there's possibly something wrong with it. But then you need to investigate it. At Lavamote we decided to be proactive instead of reactive, so we're running with the assumption that one of the dependencies in the dependency graph is already malicious when the application runs. So, how does it work? I do have a demo, if that was a longer talk, you can check that demo out, but let's look at the situation where you install a build tool for your project, and then someone puts this in your build tool's code somewhere. So it takes your GitHub token, while running in CI, and sends it somewhere. Is that great? Probably not. What LavaMode is doing, LavaMode is allowing you to generate a policy for your entire application, in this case a build process, and then run it based on that policy. The policy is automatically generated, it detects almost everything that is needed for the app to run, then you proceed to tweak the policy to the sideline, which things should be ok to allow and which shouldn't. If our analysis fails to find something, it doesn't show up in the policy, and is by default not allowed. In this case, the policy is generated with the HTTPS request and Process.env being there. What we can do is either remove those, or change them to false, which means they are not allowed, and running your build with lavamode is going to cause one of these errors to show up. Either this evil dependency requesting HTTPS package, which is not available, or failing to read env from process because process is undefined. How is that even possible? Well, it's thanks to Hardened JavaScript. We're using Hardened JavaScript behind the scenes to isolate each dependency within the same process.
2. Hardened JavaScript and Lockdown
Hardened JavaScript provides isolation by creating a compartment where code can run with controlled globals. Lockdown ensures a secure environment by preventing malicious manipulation of global prototypes. An early proposal for compartments is being considered by TC39, with input from experienced developers. Implementation is underway, offering promising results.
There's no threads, workers, or iframes involved. This is all happening in one realm or context, and we can still get good isolation. Hardened JavaScript is the compartment constructor which creates a box where you can run code in and decide what globals are going to be available and hook into it importing other things.
And then there's lockdown which makes sure that the entire environment around it, like global prototypes of object, array, and function, is put in a state where it's impossible to maliciously fiddle with them. So, no prototype pollution anymore.
And the good news is, this is becoming part of language. Well, not yet! There's an early proposal for introducing compartments in TC39, and some of the people working on it are the people responsible for giving us used strict object frees or promises. So, I'm hoping this gets in. It's going to take a while, but we already have an implementation that works.
3. LavaMode and Bundler
LavaMode is not just for Node. There's also a bundler built on the same technology and ideas, using the same structure for policy. The current bundler for Manumaskian production is Browserify-based, but we're working on a Webpack plugin. It's a work in progress and open source. Join us if you want to help out. There are still details to figure out for perfect coverage of all Webpack features.
And LavaMode is not just for Node. We're not at a Node-specific conference. There's also a bundler built on the same technology, on the same ideas, using the same structure for policy. And the bundler that we have working for Manumaskian production today is Browserify-based, because Browserify was the most flexible one of the bundlers. And that's been working for about two years now, if I recall correctly. And now we're working on getting a Webpack plugin. This is a work in progress and this is open source. So if you want to help out, please join us. There's a bunch of details about Webpack that we still need to figure out to have perfect coverage of all Webpack features. And there's a lot of Webpack features. So let me show you the Bundler now.
4. Application, Cookie Monster, and Lavamote
This is an application that imports various things, including a package called cookiemonster. Cookiemonster not only provides random quotes but also steals cookies. The app is built with webpack and includes the LavaMode plugin, codenamed Scoretrap. There are two builds, one without Scoretrap and one with it enabled. The policy currently allows the app full access, Cookie Monster access to fetch, and leftpad no access. If you want to learn more about Lavamote and Hardened JavaScript, visit my website. I'm also offering assistance in implementing Lavamote for your project.
This is an application, a very simple one, where it can import things, MJS, TypeScript, old packages, everything. And there is a package called cookiemonster that I made. And cookiemonster is giving us a random quote. And there is some environment available. Why am I showing you this? Because cookiemonster is not only giving us quotes. It's also stealing our cookies. So here's a fetch that sends our host name and cookie to the cookiemonster server.
This app is being built with webpack. There is nothing special about this configuration. It's super simple. And then this plugin. The codename for our LavaMode plugin is Scoretrap. Still a work in progress. Remember? And I have here examples of two builds. Let's run the build without Scoretrap first. So if I refresh this page, I'm going to get a message sent to my server. This is a popup from my server. It has the chocolate chip name in the cookies. This is the fetch that happened and this is the application working. We get the quote from Cookie Monster but at what price? In here, this is a build where our plugin was enabled. If I run this, I get undefined instead. What happened here is that I have some diagnostics output. We've been looking at policies for app, leftpad and Cookie Monster. So the app has access to everything. Cookie Monster still gives us quotes. But it doesn't have access to location and document, because we didn't give it that access. This is for now implemented here in the runtime. I temporarily added these hardcoded, the policy in here. Policy for the runtime for webpack is yet to be implemented but Cookie Monster is only getting fetch, leftpad is getting nothing and then app is getting pretty much everything. And that's the policy set right now.
Alright, going back to this, if you want to know more, there's a bunch of presentations about Lavamote and Hardened JavaScript on my website already. And there's a link to Mark Miller talking about his invention of SEST and Hardened JavaScript and a bunch of principles behind it. Last but not least, I'm offering to help you roll out Lavamote in your project. So if you have a serious project that you need to protect, we can install and run at least some of the Lavamote tooling for your project, easily. So let me know if you want to try it out. We're after feedback on where the incompatibilities are, because there's a very minor chunk of the NPM ecosystem that might cause trouble under Lavamote, and specifically under lockdown, where you can't modify Object Prototype, etc. So, please get in touch if you want to get involved with our open source or get Lavamote installed.
Comments