#10361·kubo

denylist: `?format=car` does not skip directly blocked CIDs

Author: lidelCreated Mar 1, 2024Updated Sep 4, 2026
Labelskind/bugneed/triage

TL;DR: ?format=car responses can contain blocks whose CIDs are on the denylist.

Problem

Path resolution goes through the denylist, so a blocked root or blocked subpath returns 410 in every response format. The CAR export does not: GetCAR in boxo/gateway walks the DAG with the raw DAGService, so a directly blocked CID inside an allowed directory ends up in the CAR body.

Not a regression. The end-to-end case in TestContentBlocking was disabled in #10360 because 0.26 already shipped this way: https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/test/cli/content_blocking_test.go#L119-L132

#10805 and ipfs/boxo#458 (200 plus a CAR header for paths the gateway cannot resolve) share the code path and the fix.

Status (September 2026)

Still reproduces on current master. The fix lives in boxo and nopfs; #10948 only carries the end-to-end tests.

Remaining work, in order:

  1. ipfs-shipyard/nopfs#50: move blocking to the blockstore and exchange so session fetches also go through the blocker (ipfs-shipyard/nopfs#34). Needs review and a tagged release.
  2. ipfs/boxo#1019: skip blocked blocks during CAR traversal and hold headers until the first block so 404/410 can still be sent. Needs a rebase on main, a green remote-car-backend conformance job, a changelog entry, and a release.
  3. #10948: bump boxo and nopfs, keep the CAR cases in TestContentBlocking, add the changelog entry.

gateway-conformance already accepts 404 for unresolvable CAR paths (ipfs/gateway-conformance#244, ipfs/gateway-conformance#245), so no conformance change is needed.