JavaScript-Code dynamisch zur Laufzeit laden und ausführen
Seite 3: Lösung: JavaScript mit vm2 ausführen
Eine Alternative zu vm, die genau dem zuvor beschriebenen Problem entgegenwirkt, ist das Package vm2, das man wie folgt installiert:
$ npm install vm2
Intern verwendet das Package Proxy-Objekte, über die der Zugriff auf die Sandbox und deren Inhalt gesteuert (und begrenzt) wird. Wie in folgendem Beispiel zu sehen, legen Entwickler über den Aufruf new VM() einen neuen Kontext an, wobei sie als Eigenschaft des übergebenen Konfigurationsobjekts wieder das Sandbox-Objekt definieren. Anschließend können sie den Code über die Methode run() ausführen:
const { VM } = require('vm2');
const sandbox = { someObject: {} };
const vm = new VM({ sandbox });
const code = `
const ForeignObject = someObject.constructor;
const ForeignFunction = ForeignObject.constructor;
const process = ForeignFunction('return process')();
const console = ForeignFunction('return console')();
console.log('Exiting process');
process.exit(0);
`;
console.log('Before executing code');
try {
vm.run(code, sandbox);
} catch (error) {
console.error(error);
}
console.log('After executing code');
Wie in der folgenden Ausgabe zu sehen, schlägt der Zugriff auf das Objekt process innerhalb des dynamisch geladenen Code fehl:
Before executing code
ReferenceError: process is not defined
at eval (eval at <anonymous> (vm.js:4:19), <anonymous>:3:1)
at vm.js:4:52
...
Ausblick
In diesem Rezept konnten Entwickler sehen, was sie beim dynamischen Laden und Ausführen von JavaScript-Code beachten sollten. Die Funktion eval() sollten sie vermeiden, da der hierüber aufgerufene Code Zugriff auf den gleichen Kontext wie der aufrufende Code hat. Das Package vm bessert diesbezüglich zwar nach, kann allerdings über entsprechende Exploits ebenfalls gehackt werden. Das Package vm2 stellt derzeit die sicherste Möglichkeit dar, um JavaScript-Code dynamisch auszuführen.
Philip Ackermann
ist CTO der Cedalo AG. Seine Schwerpunkte liegen in der Konzeption und Entwicklung von Node.js- und Java-EE-Projekten in den Bereichen Industrie 4.0 und Internet of Things.
(ane)