Arbitrary Code Execution

It is getting more usual to run code that was written by someone else – a practice that is referred to as arbitrary code execution – for tasks like automating workflows or integrating multiple services. However, like with any other strategic weapon, it comes with large-scale problems. Therefore, it has become one of our greatest concerns to understand how executing code can be done safely and most efficiently. Today, we want to tell you what we have discovered, what obstacles we have come across, and how we addressed them.
So, let’s begin by defining what arbitrary code execution (ACE) is. Typically, when people speak of software, it is the code created by developers who have written, checked, and deployed the code. But in the case of ACE, the run code is written and provided by users. This means that developers are working with code that they did not write and have not checked, which makes it a little complicated. They must assume this code could be dangerous. Their job is to securely execute it to avoid interference with other clients’ information or with our servers.
When we first began executing arbitrary code, we used VM2 (Virtual Machine 2), a sandboxed environment where JavaScript code can be executed safely within a Node.js server. The idea of VM2 is good at first: it establishes that untrusted code could be executed without harm to the system. However, as time passed, things began to deteriorate.
VM2 had a lot of security problems, and the creators of the software realised it was becoming increasingly difficult to fix these problems. That is why they decided to cease its development, and we had to look for an alternative. This was a major wake-up call for us, as the same applies to tools we considered to be very safe... one day, they get to the state where they are unsafe to use.
Running code written by someone else isn’t just tough - it's one of the hardest problems in programming. Why? Because code can do just about anything. Programming languages are powerful, and there are endless possibilities for what a piece of code might try to do. We must think of every possible scenario and ensure the code can’t do anything harmful.
Some of the biggest challenges include:
Perhaps the easiest way to guarantee that code executes without interfering with other computations is to run the code on a separate computer that is not connected to the internet and only contains the code to be run. Finally, once the code was executed, the person would have to get rid of the computer containing the code to eradicate any problems. But obviously, that’s not practical.
Lately, we have been making significant changes to upgrade some of the back-end infrastructure of our code executors. When trying to address the problems associated with the execution of arbitrary code, we were inspired by advanced sandboxing technologies employed in the Docker and the Linux kernel projects. This update doesn’t just make code execution safer – it also allows you to install dependencies in a one-time-use, disposable environment.
With these advanced techniques, it becomes possible to offer a clean environment for code runs, hence offering the highest levels of security. Regardless of the number of concurrent executions or whatever challenging tasks are being addressed, we are confident in the new setup that each execution is independent and secure. Building on Docker-inspired containers and kernel-level Linux isolation constitutes a solid starting point to efficiently and securely host and run arbitrary code.