GHSA-fj2x-735w-74vq json
gnark-crypto allows unchecked memory allocation during vector deserialization
published last yr. modified 2mo ago also GO-2025-4087
- cvss
- 7.5
- version 3.1, GitHub
- cisa kev
- Not listed
- not in CISA's catalog
- epss
- —
- no score, EPSS covers CVEs only
- public exploits
- 0
- none known
Summary
The issue has been reported by @raefko from @fuzzinglabs. Excerpts from the report: > A critical vulnerability exists in the gnark-crypto library's `Vector.ReadFrom()` function that allows an attacker to trigger arbitrary memory allocation by crafting malicious input data. An attacker can cause the verifier to attempt allocating up to 128 GB of memory with a minimal malicious input, leading to out-of-memory crashes and denial of service. > ### **Root Cause** > > > The vulnerability stems from **unchecked deserialization** of attacker-controlled length fields in the gnark-crypto library's `Vector.ReadFrom()` function. The function reads a 4-byte unsigned integer from untrusted input and directly uses it to allocate memory without any validation or bounds checking. > > ### **Vulnerable Code Path** > > ``` > User Input (Malicious Proof/Data) > ↓ > gnark Proof/Data Deserialization > ↓ > Vector.ReadFrom() (ecc/bn254/fr/vector.go:136-144) > → sliceLen := binary.BigEndian.Uint32(buf[:4]) // ← ATTACKER-CONTROLLED > → (*vector) = make(Vector, sliceLen) // ← UNCHECKED ALLOCATION > ↓ > runtime.makeslice attempts 100+ GB allocation > ↓ > fatal error: runtime: out of memory → SIGABRT > > ``` > > ### **Vulnerable Code** > > **File**: [`gnark-crypto@v0.14.0+/ecc/bn254/fr/vector.go:136-144`](https://github.com/Consensys/gnark-crypto/blob/8310aae2de6104d3fe3610e3370b2bed10c63111/ecc/bn254/fr/vector.go#L136) > > The code reads a 4-byte big-endian unsigned integer (`sliceLen`) directly from the input stream and uses it to allocate a slice without any bounds checking or validation. Each element is 32 bytes (fr.Element for BN254 curve), so an attacker can request up to: > > **Maximum Allocation**: `2^32 elements × 32 bytes = 137,438,953,472 bytes ≈ 128 GB` > > ## **Root Cause Analysis** > > The gnark-crypto library implements a generic serialization format for field element vectors. The format is: > > ``` > [4 bytes: length (n)] [n × 32 bytes: elements] > ``` > > The deserialization code **trusts** the length field implicitly without any validation. This is a classic **integer-to-allocation vulnerability** pattern, similar to issues that have affected many serialization libraries over the years.
### Impact
The issue impacts users deserializing vectors directly from untrusted sources. In case of malicious input it would lead to OOM in case the server doesn't have sufficient memory (depending on the field, but could allocate from 32GB to 196GB).
### Patches
The issue is patched in https://github.com/Consensys/gnark-crypto/pull/759. It will be backported to gnark-crypto v0.18 and v0.19.
### Workarounds
The user could manually peek into the first 4 bytes of the serialized data to estimate if the header would allocate large amounts of memory.
Patch / fix
- go github.com/consensys/gnark-crypto 0.18.1, 0.19.2
- github.com/Consensys/gnark-crypto@2e7bf91 commit
- github.com/Consensys/gnark-crypto#759 pull request
Is GHSA-fj2x-735w-74vq in your dependencies? Fencer shows which of your repositories are affected as soon as an advisory lands, and opens the fix as a pull request.
Check with FencerCVSS scores
| assigned by | version | score | vector |
|---|---|---|---|
| GitHub | 3.1 | 7.5 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
Affected packages
| ecosystem | package | affected | fixed in |
|---|---|---|---|
| go | github.com/consensys/gnark-crypto | >=0.9.1, <0.18.1 >=0.19.0, <0.19.2 |
0.18.1 0.19.2 |
Classification
- Weakness
-
- CWE-400 Uncontrolled Resource Consumption
References
-
github.com
/Consensys/gnark-crypto/pull/759
web
-
github.com
/Consensys/gnark-crypto/commit/2e7bf9190a0aac896eeec3876c87c77a35661be7
web, patch
-
github.com
/Consensys/gnark-crypto/security/advisories/GHSA-fj2x-735w-74vq
web, advisory
-
github.com
/Consensys/gnark-crypto
package
-
pkg.go.dev
/vuln/GO-2025-4087
web
Sources
- GitHub Advisory GHSA-fj2x-735w-74vq
- OSV GO-2025-4087
Fencer Intel keeps one entry per vulnerability: the CVE id wins, then GHSA, and records that alias each other are merged, except that two CVEs always keep separate entries. The same data is available as JSON.