From: Dmitry Volyntsev Date: Fri, 12 Jun 2026 01:20:01 +0000 (-0700) Subject: Webcrypto: fix buffer overflow when exporting large keys to JWK X-Git-Url: http://git.kaiwu.me/web/static/gitweb.js?a=commitdiff_plain;h=6576aa136078488e54337dc7143a696a4cdadef2;p=njs.git Webcrypto: fix buffer overflow when exporting large keys to JWK njs_export_base64url_bignum() and qjs_export_base64url_bignum() wrote BN_num_bytes() bytes into a fixed 512-byte stack buffer without a bound check. An RSA key with a modulus larger than 4096 bits (over 512 bytes), generated or imported via SPKI/PKCS8, overflowed the buffer during exportKey("jwk"). While here, add exception throwing on a parallel import part in both engines. Reported by Vaibhav Rajput. --- diff --git a/external/njs_webcrypto_module.c b/external/njs_webcrypto_module.c index bd464626..7e2b950a 100644 --- a/external/njs_webcrypto_module.c +++ b/external/njs_webcrypto_module.c @@ -2166,6 +2166,11 @@ njs_export_base64url_bignum(njs_vm_t *vm, njs_opaque_value_t *retval, size = BN_num_bytes(v); } + if (njs_slow_path(size > sizeof(buf))) { + njs_vm_range_error(vm, "JWK key too long: %uz > 512", size); + return NJS_ERROR; + } + if (njs_bn_bn2binpad(v, &buf[0], size) <= 0) { return NJS_ERROR; } @@ -3177,6 +3182,7 @@ njs_import_base64url_bignum(njs_vm_t *vm, njs_opaque_value_t *value) (void) njs_decode_base64url_length(&data, &decoded.length); if (njs_slow_path(decoded.length > sizeof(buf))) { + njs_vm_range_error(vm, "JWK key too long: %uz > 512", decoded.length); return NULL; } diff --git a/external/qjs_webcrypto_module.c b/external/qjs_webcrypto_module.c index 42ca7975..36d0d75f 100644 --- a/external/qjs_webcrypto_module.c +++ b/external/qjs_webcrypto_module.c @@ -1405,6 +1405,11 @@ qjs_export_base64url_bignum(JSContext *cx, const BIGNUM *v, size_t size) size = BN_num_bytes(v); } + if (size > sizeof(buf)) { + JS_ThrowRangeError(cx, "JWK key too long: %zu > 512", size); + return JS_EXCEPTION; + } + if (njs_bn_bn2binpad(v, &buf[0], size) <= 0) { JS_ThrowInternalError(cx, "njs_bn_bn2binpad() failed"); return JS_EXCEPTION; @@ -3076,6 +3081,7 @@ qjs_import_base64url_bignum(JSContext *cx, JSValue value) if (decoded.length > sizeof(buf)) { JS_ThrowRangeError(cx, "JWK key too long: %zu > 512", decoded.length); + JS_FreeCString(cx, (char *) data.start); return NULL; }