Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Block eval && new Function

I'm just working on writing some random puzzles on codewars.com and am curious if anyone can think of a way to eval code after the following code has been run:

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

This is in node.js, so setTimeout( "string" ) doesn't work.

like image 296
Nobody Avatar asked Feb 07 '15 01:02

Nobody


People also ask

Why eval is not recommended?

Malicious code : invoking eval can crash a computer. For example: if you use eval server-side and a mischievous user decides to use an infinite loop as their username. Terribly slow : the JavaScript language is designed to use the full gamut of JavaScript types (numbers, functions, objects, etc)… Not just strings!

What is eval function?

The eval() function evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.

What does eval mean in coding?

In some programming languages, eval , short for the English evaluate, is a function which evaluates a string as though it were an expression in the language, and returns a result; in others, it executes multiple lines of code as though they had been included instead of the line including the eval .

What does Perl eval do?

The eval function takes a character string, and evaluates it in the current perl environment, as if the character string were a line in the currently executing perl program.


1 Answers

Well, also you have module variable in node. So you can require vm package and run code using its require method:

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

UPD Well, you updated the question, but we can hack it again:

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

UPD2 Another variant:

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

UPD3 Again conditions are changed so the next variant:

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") ');

I think better to set module = undefined to make question more complex:)

UPD4 There are another variant without module:)

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

But it works only in CLI ("repl")

UPD5 Also in iojs and in node with version >= 0.11.x you can use contextify binding:

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

In node with version < 0.11.x you can use evals binding:

var evals = process.binding('evals');
var script = new evals.NodeScript(' console.log("here I am") ')
script.runInThisContext();
like image 54
alexpods Avatar answered Oct 06 '22 00:10

alexpods