Lisk sandbox vulnerability analysis and solution

Lisk sandbox vulnerability analysis and solution

background

A while ago, Daniel Larimer, the founder of BitShares, questioned a series of problems with the Lisk system. Although most of the problems have been responded to positively by Max, one of the founders of Lisk (see this for details), there is still one problem that Max has not responded to or has not yet proposed a solution.

That’s the environment in which the Lisk sidechain operates, Larimer said.

“Most of the problems Lisk faces can be solved with a highly customized JavaScript environment.”

Otherwise, Lisk's system faces two major challenges:

First and foremost, Lisk’s current sandbox mechanism is not sufficient to restrict the permissions of the sidechain code, which means that untrusted code cannot be run, which may steal key information from the server or directly damage the server.

Secondly, regarding the sidechain developers, the sidechain code of Lisk runs in a fully capable JavaScript environment, which contains some functions that may cause uncertainty, such as Math.random. The official development documentation of Lisk specifically points out that developers are expected to avoid these functions, which will cause a mental burden on developers. If it is a customized JavaScript environment, the functions that cause uncertainty will be directly eliminated, and developers do not need to spend extra energy to avoid those traps.

Lisk's sandbox security issues

Let's first talk about why we need sandboxes. Sandboxes are a widely used security measure in cloud computing platforms. They are an access control mechanism that aims to limit the permissions of application codes and prevent them from arbitrarily accessing and damaging the system. In cloud computing platforms, application codes are implemented by various third-party developers, and their codes cannot be trusted. Sandboxes are needed to provide a layer of isolation so that these application codes can only do limited things.

Lisk is very similar to a cloud computing platform in the blockchain field. They provide some services and allow third-party developers to build their own applications (i.e. dapps) based on these services.
Therefore, Lisk also needs a sandbox mechanism to ensure that the authors of dapps cannot do evil. Lisk's approach is to provide a customized nodejs environment to achieve this goal.
The specific implementation is in this code, https://github.com/LiskHQ/lisk-node/blob/v0.12.14-lisk/src/node_sandbox.cc

After analysis, I found that this sandbox is not worthy of its name. It only uses pipes to achieve inter-process communication, and it is achieved in a roundabout way. The inter-process communication of nodejs can be directly implemented through javascript code, so why use c++ to implement it?

With this question and some expectations, I did an experiment myself.

I first create a hello world sidechain using lisk-cli

lisk-cli dapp -a

Then I added a piece of code at the entrance of the sidechain program dapps/<dappid>/index.js

console.log(require("fs").readFileSync("../../config.json"))

Then run it, and I get all the passwords of the trustees of this server master node

"forging": {
"secret": [
"wKyoJM1vS4ucHmWvxDSdcpC23mJwqfg3G6MKZoXaFfcnWHTqo7",
"2aTWYPpQidVunxTg3y8YESYps7za6f9d4wYn9Gy2GuGnE7JX7V",
"65uZNjL36Bdg2tkJnueYkd2n6YPe76fpdeYtgu7fso1m385mwD",
…………

Sure enough, this sandbox did not play an isolation role and had administrator privileges, which was equivalent to opening the door to hackers.

Some people say that the Lisk system has a second-level password. Even if you get their first-level password, you still can't steal their money.

Some people also say that through Linux's own permission mechanism, the side chain code can be given a low-level user so that it cannot access other users' files.

These are only temporary solutions and not a fundamental solution. The fundamental solution is to make the sandbox live up to its name and achieve true environmental isolation as Lisk had envisioned, so that the sidechain code is completely unknown to the outside world.

Solution

So, how to achieve a real sandbox? There are many solutions, such as skipping nodejs and using the v8 engine directly, or using process-level permission control, such as SetWindowsHookEx in Windows. Of course, Lisk currently does not plan to support the full version of the Windows wallet, so seccomp technology can be used in Linux systems.
I have a simpler method here, which is to use the vm module that comes with nodejs.

The first step is to create a native javascript virtual machine

var vm = require('vm');
var context = vm.createContext();
vm.runInContext(sideChainCode, context);

These few lines of code complete the isolation of the sidechain code. Only pure operation logic can be performed in sideChainCode, and only a small amount of javascript standard library built into the v8 engine can be used. There is not even setTimeout or console.log.

We need to do some extra work.

For example, add setTimeout and clearTimeout to the runtime environment

context.setTimeout= function(fn, delay) {
if (typeof(fn) == 'string') {
setTimeout(new Function(fn), delay)
} else {
setTimeout(fn, delay)
}
};
context.clearTimeout = clearTimeout;

Added log printing function to forward the side chain logs to the main system

global.print = send.bind(global, 'stdout');
global.console = { log: send.bind(global, 'stdout') };
global.process = {
stdout: { write: send.bind(global, 'stdout') }
};
global.postMessage = send.bind(global, 'message');

In addition, you can disable functions that cause uncertainty

global.Math.random = undefined;

After all this is done, the access rights of the sidechain code are limited to a narrow range. They cannot use the standard libraries built into nodejs, such as require, fs, and http.

This achieves the purpose of security, but it raises another problem, which is the functionality problem. Those additional libraries cannot be used, and it is too inconvenient to only have the js standard library. Many complex functions cannot be implemented, especially without require, even modularization is impossible.

So we need a second step.

Step 2 webpack

Webpack is a commonly used packaging solution for front-end projects, which is used to manage front-end projects in a modular way. Many people overlook the fact that webpack is also applicable to the back-end, and can package libraries in node_modules and even some of the built-in libraries of nodejs.

That is to say, all js libraries that can be used on the front end, except those related to UI, can also be used in the side chain sandbox, such as async, bytebuffer, crypto, js-nacl, bignum, etc., which is enough for the side chain.
Those unusable libraries, such as file system, multi-process, and network modules, are exactly what we want to abandon.

The combination of vm + webpack is perfect.

This is the benefit that the ever-changing front-end technology brings to the JavaScript language, and it is also something that new languages ​​such as Ethereum's Solidity cannot match.

But we still need some finishing touches

Step 3: Clear the obstacles

At present, some places in the side chain code use some relatively complex libraries, such as ed2curve, which involves a lot of dependencies. We think it is unnecessary. This part of the function can be provided in the main chain and provided to the side chain in the form of an API through inter-process communication.

This can also reduce the burden of sidechain code and make sidechain developers more relaxed. The impact of these codes on the entire framework is very small and can be ignored, but the libraries they depend on occupy more than half of the code, including some operations that are not allowed in the sandbox environment.

After analysis, I found that I only need to disable two functions in modules/api/crypto.js

Crypto.prototype.encrypt
Crypto.prototype.decrypt

In addition, js-nacl library depends on the fs module, but the related functions are not used. Temporarily, by manually modifying it, the fs-related code can be removed and it can be packaged and run normally.

Finally, I packaged a complete sidechain project and the key codes in the mainchain framework and put them here. http://o7dyh3w0x.bkt.clouddn.com/asch-sandbox-solution.tar.gz

I hope this can serve as a reference for the Lisk development team so that they can fix the vulnerability before they open registration for sidechain applications.


<<:  Wright, who claims to be 'Satoshi Nakamoto', applies for hundreds of Bitcoin and blockchain patents, and a patent war is coming

>>:  Bitcoin: The best blockchain application

Recommend

What are the facial features of women with miserable fate?

Some girls are born with good lives, while some g...

Chart, learn and explore: CoinDesk launches ICO tracking tool

Rage Review : ICO has rapidly developed into the ...

What kind of women are blessed?

What kind of women are blessed? 1. Women with del...

See your future fortune from your facial features

From the perspective of physiognomy, a person'...

How to tell a person's personality from his index finger

1. People with long and straight index fingers li...

Will you become a rich person by reading your palm?

Will you become a rich person by reading your pal...

How to read a man's eyebrows

Eyebrows are the most important of the five facia...

Why does the forehead turn black?

Why does the forehead turn black? We often see on...

What does a mole on the calf mean?

In medicine, moles are called black cytoplasm, an...