阻止评估和新功能

Block eval && new Function

本文关键字:新功能 评估      更新时间:2023-09-26

我只是在 codewars.com 上编写一些随机谜题,我很好奇是否有人能在运行以下代码后想到一种评估代码的方法:

eval = function(){};
delete Function.prototype.constructor;
Function = undefined;
// the following are to block require('vm') -- if anyone wants to run this
// in production it may be better to block that one module (others?)
require = undefined;
module.__proto__.require = undefined; // added this due to alexpod's answer, modified due to Fabrício Matté's :)
module.constructor = undefined; // added this due to alexpod's answer

这是在节点.js中,所以setTimeout( "string" )不起作用。

好吧,你在node中也有module变量。因此,您可以使用其require方法要求vm包并运行代码:

var vm = module.require('vm');
vm.runInThisContext(' console.log("hello") ');

UPD好吧,您更新了问题,但我们可以再次破解它:

var vm = module.constructor.prototype.require('vm');
vm.runInThisContext(' console.log("hello") ');

UPD2另一个变体:

var vm = module.constructor._load('vm');
vm.runInThisContext(' console.log("hello") ');

UPD3再次更改条件,以便下一个变体:

module.constructor.prototype._compile(' console.log("again hacked") ');
// or
module.__proto__._compile(' console.log("again hacked") ');
// or
Object.getPrototypeOf(module)._compile(' console.log("again hacked") ');

我认为最好设置module = undefined以使问题更复杂:(

UPD4还有另一种没有module :)的变体

process.stdin.push(' console.log("here we are") 'n ');

但它仅适用于 CLI("repl"(

UPD5同样在版本>= 0.11.x 的 iojsnode中,您可以使用contextify绑定:

var contextify = process.binding('contextify');
var script = new contextify.ContextifyScript(' console.log("im here, buddy") ');
script.runInThisContext();

在版本 <0.11.x 的node中,您可以使用evals绑定:

var evals = process.binding('evals');
var script = new evals.NodeScript(' console.log("here I am") ')
script.runInThisContext();

module.require = undefined;是不够的,因为require是从模块原型继承而来的:

module.require = undefined;
var vm = module.__proto__.require('vm');
vm.runInThisContext('console.log(1)');

相反,您应该:

module.__proto__.require = undefined;
// now this fails and you can't use the __proto__ trick:
var vm = module.require('vm');

使用 GeneratorFunction 构造函数:

(function*(){}).constructor('console.log(1);')().next().value;