Fix stack overflow in CVE-2023-31922 (#157)

isArray and proxy isArray can call each other indefinitely in a mutually
recursive loop.

Add a stack overflow check in the js_proxy_isArray function before calling
`JS_isArray(ctx, s->target)`.

Original issue: https://github.com/bellard/quickjs/issues/178
CVE: https://nvd.nist.gov/vuln/detail/CVE-2023-31922
This commit is contained in:
Nick Vatamaniuc 2023-12-01 10:31:36 -05:00 committed by GitHub
parent bf1facaea3
commit 6b3bed1740
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 0 deletions

View file

@ -43612,6 +43612,12 @@ static int js_proxy_isArray(JSContext *ctx, JSValueConst obj)
JSProxyData *s = JS_GetOpaque(obj, JS_CLASS_PROXY);
if (!s)
return FALSE;
if (js_check_stack_overflow(ctx->rt, 0)) {
JS_ThrowStackOverflow(ctx);
return -1;
}
if (s->is_revoked) {
JS_ThrowTypeErrorRevokedProxy(ctx);
return -1;

View file

@ -707,6 +707,25 @@ function test_generator()
assert(v.value === undefined && v.done === true);
}
/* CVE-2023-31922 */
function test_proxy_is_array()
{
for (var r = new Proxy([], {}), y = 0; y < 331072; y++)
r = new Proxy(r, {});
try {
/* Without ASAN */
assert(Array.isArray(r));
} catch(e) {
/* With ASAN expect InternalError "stack overflow" to be raised */
if (e instanceof InternalError) {
assert(e.message, "stack overflow", "Stack overflow error was not raised")
} else {
throw e;
}
}
}
test();
test_function();
test_enum();
@ -724,3 +743,4 @@ test_map();
test_weak_map();
test_weak_set();
test_generator();
test_proxy_is_array();