eval_villain icon indicating copy to clipboard operation
eval_villain copied to clipboard

Direct vs indirect eval

Open mikesamuel opened this issue 5 years ago • 2 comments

This is more of an fyi since I have no suggested fix.

applyEvalVillain("eval") turns direct eval into indirect eval

https://github.com/swoops/eval_villain/blob/8c49852dee59d2541dcb4a5cede68b76c0878caf/src/js/switcheroo.js#L385

Since eval !== %eval%, all eval becomes direct eval.

You can see the difference in

const x = 'indirect';
(() => {
  const x = 'direct';
  console.log(`eval(x) => ${ eval('x') }`);  // -> indirect
  console.log(`(0, eval)(x) => ${ (0, eval)('x') }`);  // -> direct
})();

This happens because of step 6.a in 12.3.4.1

  1. If Type(ref) is Reference and IsPropertyReference(ref) is false and GetReferencedName(ref) is "eval", then a. If SameValue(func, %eval%) is true, then

when evaluating function calls where the function is the identifier eval.

mikesamuel avatar Jul 03 '19 20:07 mikesamuel

I was unaware of this behavior.

This could lead to false positives/negatives or breaking sites. It could also be used to identify when Eval Villain is hooking eval in the page.

Thanks

swoops avatar Jul 08 '19 20:07 swoops

It could also be used to identify when Eval Villain is hooking eval in the page.

Yeah.

function isEvalHooked() {
  var Object = 0;  // Mask the global.
  return eval('typeof Object') !== 'number';
}

console.log(isEvalHooked());  // -> false
eval = new Proxy(eval, {});
console.log(isEvalHooked());  // -> true

mikesamuel avatar Jul 09 '19 14:07 mikesamuel