Skip to content

Unbounded DAG pinning can exhaust filecoin-pin server resources

Moderate
BigLep published GHSA-m5ph-mmg5-6w5h Jun 26, 2026

Package

npm filecoin-pin (npm)

Affected versions

<=1.1.0

Patched versions

1.1.1

Description

Summary

The IPFS Pinning Service API implementation accepts a caller-controlled CID through POST /pins, queues background processing, and then recursively fetches the full DAG with helia.pins.add(cid). The route and background pinning path do not enforce a request rate limit, per-user quota, maximum DAG byte count, maximum block count, traversal timeout, or concurrent pinning limit.

An authenticated caller, or an unauthenticated caller when the server is started with ALLOW_NO_AUTH=true, can submit one or more pins whose CIDs resolve to very large DAGs. The server writes fetched blocks to CAR files under carStoragePath and can consume disk, network, CPU, and libp2p resources until the process or host becomes unavailable.

Details

POST /pins validates only that the request body contains a syntactically valid CID string, then forwards it to the pin store:

  • src/filecoin-pinning-server.ts:304-342 accepts the request, parses cid with CID.parse, and calls pinStore.pin(request.user, cidObject, parsed.options).
  • src/filecoin-pin-store.ts:153-188 stores the pin as queued and schedules _processPinInBackground with setTimeout. There is no queue, semaphore, or global cap around this scheduling.
  • src/filecoin-pin-store.ts:211-217 creates a per-pin Helia node and forwards caller-supplied origins.
  • src/filecoin-pin-store.ts:260-274 walks the full DAG with for await (const pinnedCid of helia.pins.add(cid)).
  • src/create-pinning-helia.ts:47-80 creates a libp2p/Helia node with the Bitswap block broker and no application-level resource limits.
  • src/core/car/car-blockstore-base.ts:65-107 writes every fetched block and updates stats.totalSize only after writing.
  • src/core/car/car-file-backend.ts:84-93 streams blocks to the CAR writer on disk.

The Helia node created for each pin has no bootstrap or mDNS configuration (src/create-pinning-helia.ts:57). A public CID alone may therefore not be fetchable unless the node can reach a content source. In practice, the API also accepts origins, so an attacker can supply a reachable attacker-controlled libp2p origin that serves a large DAG and cause the server to retrieve it.

Impact

Successful exploitation affects availability:

  • Disk exhaustion from unbounded CAR files in carStoragePath.
  • Network exhaustion from recursive Bitswap retrieval.
  • CPU and memory pressure from concurrent libp2p/Helia pin operations.
  • Service degradation or process failure for other users of the daemon.
  • Operational cost and manual recovery burden from large partial CAR files.

The default daemon configuration reduces exposure because the server binds to localhost and refuses to start without an access token unless ALLOW_NO_AUTH=true. The finding is most significant when the daemon is exposed beyond localhost, when the token is shared across untrusted users, or when the no-auth mode is enabled.

PoC

curl -X POST "https://target.example/pins" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "cid": "CID_OF_LARGE_DAG",
    "origins": ["/ip4/203.0.113.10/tcp/4001/p2p/ATTACKER_PEER_ID"],
    "meta": { "purpose": "resource-exhaustion-validation" }
  }'

Submitting many such requests concurrently accelerates resource pressure because each request schedules independent background processing.

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

CVE ID

CVE-2026-62300

Weaknesses

Uncontrolled Resource Consumption

The product does not properly control the allocation and maintenance of a limited resource. Learn more on MITRE.

Credits