ghsa-fj2x-735w-74vq
Vulnerability from github
Published
2025-10-30 17:10
Modified
2025-11-05 22:15
Summary
gnark-crypto allows unchecked memory allocation during vector deserialization
Details

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

Filegnark-crypto@v0.14.0+/ecc/bn254/fr/vector.go:136-144

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 Allocation2^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.

Show details on source website


{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/consensys/gnark-crypto"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.9.1"
            },
            {
              "fixed": "0.18.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/consensys/gnark-crypto"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.19.0"
            },
            {
              "fixed": "0.19.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "0.19.0"
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-10-30T17:10:40Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "The issue has been reported by @raefko from @fuzzinglabs. Excerpts from the report:\n\u003e A critical vulnerability exists in the gnark-crypto library\u0027s\u00a0`Vector.ReadFrom()`\u00a0function 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.\n\u003e ### **Root Cause**\n\u003e \n\u003e \n\u003e The vulnerability stems from\u00a0**unchecked deserialization**\u00a0of attacker-controlled length fields in the gnark-crypto library\u0027s\u00a0`Vector.ReadFrom()`\u00a0function. The function reads a 4-byte unsigned integer from untrusted input and directly uses it to allocate memory without any validation or bounds checking.\n\u003e \n\u003e ### **Vulnerable Code Path**\n\u003e \n\u003e ```\n\u003e User Input (Malicious Proof/Data)\n\u003e          \u2193\n\u003e gnark Proof/Data Deserialization\n\u003e          \u2193\n\u003e Vector.ReadFrom() (ecc/bn254/fr/vector.go:136-144)\n\u003e   \u2192 sliceLen := binary.BigEndian.Uint32(buf[:4])   // \u2190 ATTACKER-CONTROLLED\n\u003e   \u2192 (*vector) = make(Vector, sliceLen)             // \u2190 UNCHECKED ALLOCATION\n\u003e          \u2193\n\u003e runtime.makeslice attempts 100+ GB allocation\n\u003e          \u2193\n\u003e fatal error: runtime: out of memory \u2192 SIGABRT\n\u003e \n\u003e ```\n\u003e\n\u003e ### **Vulnerable Code**\n\u003e \n\u003e **File**:\u00a0[`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)\n\u003e \n\u003e 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:\n\u003e \n\u003e **Maximum Allocation**:\u00a0`2^32 elements \u00d7 32 bytes = 137,438,953,472 bytes \u2248 128 GB`\n\u003e \n\u003e ## **Root Cause Analysis**\n\u003e \n\u003e The gnark-crypto library implements a generic serialization format for field element vectors. The format is:\n\u003e \n\u003e ```\n\u003e [4 bytes: length (n)] [n \u00d7 32 bytes: elements]\n\u003e ```\n\u003e \n\u003e The deserialization code\u00a0**trusts**\u00a0the length field implicitly without any validation. This is a classic\u00a0**integer-to-allocation vulnerability**\u00a0pattern, similar to issues that have affected many serialization libraries over the years.\n\n### Impact\n\nThe issue impacts users deserializing vectors directly from untrusted sources. In case of malicious input it would lead to OOM in case the server doesn\u0027t have sufficient memory (depending on the field, but could allocate from 32GB to 196GB).\n\n### Patches\n\nThe issue is patched in https://github.com/Consensys/gnark-crypto/pull/759. It will be backported to gnark-crypto v0.18 and v0.19.\n\n### Workarounds\n\nThe user could manually peek into the first 4 bytes of the serialized data to estimate if the header would allocate large amounts of memory.",
  "id": "GHSA-fj2x-735w-74vq",
  "modified": "2025-11-05T22:15:15Z",
  "published": "2025-10-30T17:10:40Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/Consensys/gnark-crypto/security/advisories/GHSA-fj2x-735w-74vq"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Consensys/gnark-crypto/pull/759"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Consensys/gnark-crypto/commit/2e7bf9190a0aac896eeec3876c87c77a35661be7"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/Consensys/gnark-crypto"
    },
    {
      "type": "WEB",
      "url": "https://pkg.go.dev/vuln/GO-2025-4087"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "gnark-crypto allows unchecked memory allocation during vector deserialization"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…