GHSA-m5ph-mmg5-6w5h
Dashboard / Vulnerabilities / GHSA-m5ph-mmg5-6w5h
Summary: filecoin-pin: Unbounded DAG pinning can exhaust server resources
Details: ## 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 ```bash 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.
References: https://github.com/filecoin-project/filecoin-pin/security/advisories/GHSA-m5ph-mmg5-6w5h, https://nvd.nist.gov/vuln/detail/CVE-2026-62300, https://github.com/filecoin-project/filecoin-pin/commit/8db22b47899deb78dadf415fc477cae4bd6e82c2, https://github.com/filecoin-project/filecoin-pin/commit/afa019307db23a703737675e94316edcc6572050, https://github.com/filecoin-project/filecoin-pin, https://github.com/filecoin-project/filecoin-pin/releases/tag/v1.1.1
Affected packages
Package
Name: filecoin-pin
Purl: pkg:npm/filecoin-pin
Affected ranges
Type: SEMVER
Events:
