Vulnerabilidades de QuickJS
CVEs publicadas que afetam produtos de QuickJS: 7 registro(s), com severidade, exploração e correções.
CVE-2025-62496
Alta · 8.8
CWE-190 16/10/2025
Integer overflow in js_bigint_from_string in QuickJS
A vulnerability exists in the QuickJS engine's BigInt string parsing logic (js_bigint_from_string) when attempting to create a BigInt from a string with an excessively large number of digits.
The function calculates the necessary number of bits (n_bits) required to store the BigInt using the formula:
$$\text{n\_bits} = (\text{n\_digits} \times 27 + 7) / 8 \quad (\text{for radix 10})$$
* For large input strings (e.g., $79,536,432$ digits or more for base 10), the intermediate calculation $(\text{n\_digits} \times 27 + 7)$ exceeds the maximum value of a standard signed 32-bit integer, resulting in an Integer Overflow.
* The resulting n_bits value becomes unexpectedly small or even negative due to this wrap-around.
* This flawed n_bits is then used to compute n_limbs, the number of memory "limbs" needed for the BigInt object. Since n_bits is too small, the calculated n_limbs is also significantly underestimated.
* The function proceeds to allocate a JSBigInt object using this underestimated n_limbs.
* When the function later attempts to write the actual BigInt data into the allocated object, the small buffer size is quickly exceeded, leading to a Heap Out-of-Bounds Write as data is written past the end of the allocated r->tab array.
CVE-2025-62495
Alta · 8.8
CWE-191 16/10/2025
Type confusion in string addition in QuickJS
An integer overflow vulnerability exists in the QuickJS regular expression engine (libregexp) due to an inconsistent representation of the bytecode buffer size.
* The regular expression bytecode is stored in a DynBuf structure, which correctly uses a $\text{size}\_\text{t}$ (an unsigned type, typically 64-bit) for its size member.
* However, several functions, such as re_emit_op_u32 and other internal parsing routines, incorrectly cast or store this DynBuf $\text{size}\_\text{t}$ value into a signed int (typically 32-bit).
* When a large or complex regular expression (such as those generated by a recursive pattern in a Proof-of-Concept) causes the bytecode size to exceed $2^{31}$ bytes (the maximum positive value for a signed 32-bit integer), the size value wraps around, resulting in a negative integer when stored in the int variable (Integer Overflow).
* This negative value is subsequently used in offset calculations. For example, within functions like re_parse_disjunction, the negative size is used to compute an offset (pos) for patching a jump instruction.
* This negative offset is then incorrectly added to the buffer pointer (s->byte\_code.buf + pos), leading to an out-of-bounds write on the first line of the snippet below:
put_u32(s->byte_code.buf + pos, len);
CVE-2025-62494
Alta · 8.8
CWE-704 16/10/2025
Type confusion in string addition in QuickJS
A type confusion vulnerability exists in the handling of the string addition (+) operation within the QuickJS engine.
* The code first checks if the left-hand operand is a string.
* It then attempts to convert the right-hand operand to a primitive value using JS_ToPrimitiveFree. This conversion can trigger a callback (e.g., toString or valueOf).
* During this callback, an attacker can modify the type of the left-hand operand in memory, changing it from a string to a different type (e.g., an object or an array).
* The code then proceeds to call JS_ConcatStringInPlace, which still treats the modified left-hand value as a string.
This mismatch between the assumed type (string) and the actual type allows an attacker to control the data structure being processed by the concatenation logic, resulting in a type confusion condition. This can lead to out-of-bounds memory access, potentially resulting in memory corruption and arbitrary code execution in the context of the QuickJS runtime.
CVE-2025-62493
Média · 6.5
CWE-125 16/10/2025
Leitura heap fora dos limites na conversão de BigInt para string no QuickJS
Existe uma vulnerabilidade na lógica de conversão de BigInt para string do motor QuickJS (js_bigint_to_string1), causada por um cálculo incorreto do número de dígitos necessários, o que leva à leitura de memória além da estrutura BigInt alocada. * A função determina o número de caracteres (n_digits) necessários para a representação em string pelo cálculo: n_digits = (n_bits + log2_radix - 1) / log2_radix. Essa fórmula apresenta erro de uma unidade (off-by-one) em certos casos extremos ao calcular os limbs de memória necessários. Por exemplo, um BigInt de 127 bits usando radix 32 (onde log2_radix = 5) é calculado como precisando de n_digits = 26. * O número máximo de bits efetivamente armazenados é n_bits = 127, o que exige apenas dois limbs de 64 bits (JS_LIMB_BITS = 64). * O laço de conversão itera n_digits = 26 vezes, tentando ler 5 bits em cada iteração, totalizando 26 x 5 = 130 bits. * Nas últimas iterações do laço, o código tenta ler dados que se estendem por dois limbs: c = (r->tab[pos] >> shift) | (r->tab[pos + 1] << (JS_LIMB_BITS - shift)); * Como o BigInt foi alocado com apenas dois limbs, a leitura de r->tab[pos + 1] torna-se uma leitura fora dos limites (Out-of-Bounds Read) quando pos aponta para o último limb válido (por exemplo, pos = 1). Essa vulnerabilidade permite que um atacante faça o motor ler e processar dados da memória imediatamente posterior ao buffer do BigInt. Isso pode levar à divulgação de informações sensíveis armazenadas no heap adjacente ao objeto BigInt.
CVE-2025-62492
Média · 6.5
CWE-125 16/10/2025
Heap out-of-bounds read in js_typed_array_indexOf in QuickJS
A vulnerability stemming from floating-point arithmetic precision errors exists in the QuickJS engine's implementation of TypedArray.prototype.indexOf() when a negative fromIndex argument is supplied.
* The fromIndex argument (read as a double variable, $d$) is used to calculate the starting position for the search.
* If d is negative, the index is calculated relative to the end of the array by adding the array's length (len) to d:
$$d_{new} = d + \text{len}$$
* Due to the inherent limitations of floating-point arithmetic, if the negative value $d$ is extremely small (e.g., $-1 \times 10^{-20}$), the addition $d + \text{len}$ can result in a loss of precision, yielding an outcome that is exactly equal to $\text{len}$.
* The result is then converted to an integer index $k$: $k = \text{len}$.
* The search function proceeds to read array elements starting from index $k$. Since valid indices are $0$ to $\text{len}-1$, starting the read at index $\text{len}$ is one element past the end of the array.
This allows an attacker to cause an Out-of-Bounds Read of one element immediately following the buffer. While the scope of this read is small (one element), it can potentially lead to Information Disclosure of adjacent memory contents, depending on the execution environment.
CVE-2025-62491
Alta · 8.8
CWE-416 16/10/2025
Use-after-free in js_std_promise_rejection_check in QuickJS
A Use-After-Free (UAF) vulnerability exists in the QuickJS engine's standard library when iterating over the global list of unhandled rejected promises (ts->rejected_promise_list).
* The function js_std_promise_rejection_check attempts to iterate over the rejected_promise_list to report unhandled rejections using a standard list loop.
* The reason for a promise rejection is processed inside the loop, including calling js_std_dump_error1(ctx, rp->reason).
* If the promise rejection reason is an Error object that defines a custom property getter (e.g., via Object.defineProperty), this getter is executed during the error dumping process.
* The malicious custom getter can execute JavaScript code that calls catch() on the same rejected promise being processed.
* Calling catch() internally triggers js_std_promise_rejection_tracker, which then removes and frees the current promise entry (JSRejectedPromiseEntry) from the rejected_promise_list.
* Since the list iteration continues using the now-freed memory pointer (el), the subsequent loop access results in a Use-After-Free condition.
CVE-2025-62490
Alta · 8.8
CWE-416 16/10/2025
Use-after-free in js_print_object in QuickJS
In quickjs, in js_print_object, when printing an array, the function first fetches the array length and then loops over it. The issue is, printing a value is not side-effect free. An attacker-defined callback could run during js_print_value, during which the array could get resized and len1 become out of bounds. This results in a use-after-free.A second instance occurs in the same function during printing of a map or set objects. The code iterates over ms->records list, but once again, elements could be removed from the list during js_print_value call.