Filecoin Pin is an IPFS Pinning Service API implementation that pins to Filecoin's PDP service. In daemon deployments up to and including version 1.1.0, `POST /pins` in `src/filecoin-pinning-server.ts` checks a caller-supplied CID with `CID.parse` and passes it to `pinStore.pin`, but does not enforce request rate limits or per-user quotas. In `src/filecoin-pin-store.ts`, each pin independently schedules `_processPinInBackground` with `setTimeout` without a queue, semaphore or concurrency cap, then recursively traverses the full DAG using `helia.pins.add(cid)`. The per-pin Helia/Bitswap node in `src/create-pinning-helia.ts` has no application-level byte, block or traversal-time limits. Blocks are written under `carStoragePath` by `src/core/car/car-blockstore-base.ts` and `src/core/car/car-file-backend.ts`, with `stats.totalSize` updated only after writing. An authenticated caller, or an anonymous caller when `ALLOW_NO_AUTH=true`, can submit large DAGs and exhaust disk, network, CPU, memory and libp2p resources, causing service degradation or host/process failure and leaving partial CAR files requiring recovery. The default localhost binding and token requirement reduce exposure. Because nodes have no bootstrap or mDNS configuration, a CID alone may not be fetchable, but caller-supplied `origins` can point to a reachable attacker-controlled libp2p source; concurrent requests accelerate resource pressure. Version 1.1.1 documents operational mitigations but does not implement the missing resource controls.
Filecoin Pin is an IPFS Pinning Service API implementation that pins to Filecoin's PDP service. In daemon deployments up to and including version 1.1.0, `POST /pins` in `src/filecoin-pinning-server.ts` checks a caller-supplied CID with `CID.parse` and passes it to `pinStore.pin`, but does not enforce request rate limits or per-user quotas. In `src/filecoin-pin-store.ts`, each pin independently schedules `_processPinInBackground` with `setTimeout` without a queue, semaphore or concurrency cap, then recursively traverses the full DAG using `helia.pins.add(cid)`. The per-pin Helia/Bitswap node in `src/create-pinning-helia.ts` has no application-level byte, block or traversal-time limits. Blocks are written under `carStoragePath` by `src/core/car/car-blockstore-base.ts` and `src/core/car/car-file-backend.ts`, with `stats.totalSize` updated only after writing. An authenticated caller, or an anonymous caller when `ALLOW_NO_AUTH=true`, can submit large DAGs and exhaust disk, network, CPU, memory and libp2p resources, causing service degradation or host/process failure and leaving partial CAR files requiring recovery. The default localhost binding and token requirement reduce exposure. Because nodes have no bootstrap or mDNS configuration, a CID alone may not be fetchable, but caller-supplied `origins` can point to a reachable attacker-controlled libp2p source; concurrent requests accelerate resource pressure. Version 1.1.1 documents operational mitigations but does not implement the missing resource controls.
Filecoin Pin is an IPFS Pinning Service API implementation that pins to Filecoin's PDP service. In daemon deployments up to and including version 1.1.0, `POST /pins` in `src/filecoin-pinning-server.ts` checks a caller-supplied CID with `CID.parse` and passes it to `pinStore.pin`, but does not enforce request rate limits or per-user quotas. In `src/filecoin-pin-store.ts`, each pin independently schedules `_processPinInBackground` with `setTimeout` without a queue, semaphore or concurrency cap, then recursively traverses the full DAG using `helia.pins.add(cid)`. The per-pin Helia/Bitswap node in `src/create-pinning-helia.ts` has no application-level byte, block or traversal-time limits. Blocks are written under `carStoragePath` by `src/core/car/car-blockstore-base.ts` and `src/core/car/car-file-backend.ts`, with `stats.totalSize` updated only after writing. An authenticated caller, or an anonymous caller when `ALLOW_NO_AUTH=true`, can submit large DAGs and exhaust disk, network, CPU, memory and libp2p resources, causing service degradation or host/process failure and leaving partial CAR files requiring recovery. The default localhost binding and token requirement reduce exposure. Because nodes have no bootstrap or mDNS configuration, a CID alone may not be fetchable, but caller-supplied `origins` can point to a reachable attacker-controlled libp2p source; concurrent requests accelerate resource pressure. Version 1.1.1 documents operational mitigations but does not implement the missing resource controls.
## 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.
EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.
Original publisher date fields
datePublished: Oct 30, 2026, 8:15:23 PM
dateUpdated: Nov 2, 2026, 3:01:53 PM
No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.
NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.
Source analysis status: Deferred
Weakness classifications: CWE-400
Original publisher date fields
published: 2026-10-30T21:17:13.670
lastModified: 2026-11-02T19:35:33.347
No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.