Skip to content

fix(api): require CID ownership to unpin IPFS content (IDOR) - #2

Closed
Dennis-Ritchie1 wants to merge 2 commits into
mainfrom
fix/1155-ipfs-unpin-idor
Closed

fix(api): require CID ownership to unpin IPFS content (IDOR)#2
Dennis-Ritchie1 wants to merge 2 commits into
mainfrom
fix/1155-ipfs-unpin-idor

Conversation

@Dennis-Ritchie1

Copy link
Copy Markdown
Owner

Summary

  • POST /api/ipfs/unpin previously authorized any request that presented a valid JWT — since a fresh JWT is free to obtain (no on-chain history required), any wallet could unpin any other user's IPFS metadata by CID.
  • Adds a pin-ownership registry (api/_lib/pinOwnership.ts) populated at upload time by upload-json.ts / upload-file.ts, and a new api/ipfs/unpin.ts endpoint that resolves a CID back to the wallet that pinned it before calling Pinata.
  • A CID with no ownership record on file is denied by default (never allow-by-default for unindexed content), matching the acceptance criteria in Any authenticated wallet can unpin any user's IPFS metadata (IDOR) Favourorg/Stellar-forge#1155.
  • Every unpin attempt — allowed or rejected — is audit-logged with address, cid, and outcome.
  • Documented the new control in SECURITY.md under "Known security considerations".
  • Unrelated blocker fix bundled in: frontend/package.json had react bumped to 19.2.8 (chore(deps): bump react from 19.2.7 to 19.2.8 in /frontend Favourorg/Stellar-forge#1049) without react-dom, which hard-errors at runtime and broke the entire frontend test suite / this repo's pre-push hook. Aligned react-dom to 19.2.8 so the branch could be pushed through the hook cleanly.

Test plan

  • npx vitest run api/ipfs/unpin.test.ts — 6/6 passing: owner unpins own CID (allow), non-owner denied (403), unindexed CID denied by default (403), malformed cid rejected (400), missing JWT rejected (401), non-POST rejected (405)
  • npm test -- --run in frontend/ — 609/609 passing after the react-dom fix

Closes Favourorg#1155

🤖 Generated with Claude Code

https://claude.ai/code/session_018B7HTwSnjuY1WoS86cpQfF

POST /api/ipfs/unpin previously authorized any wallet with a valid JWT to
unpin any CID, since a fresh JWT costs nothing (challenge/response needs no
on-chain history) and the wallet address was never checked against who
actually pinned the content.

Add a pin-ownership registry (api/_lib/pinOwnership.ts) populated by
upload-json.ts / upload-file.ts at pin time, and a new unpin.ts endpoint
that resolves a CID back to its pinning wallet before calling Pinata. A CID
with no ownership record is denied by default rather than allowed, and
every attempt (allowed or rejected) is audit-logged with address, cid, and
outcome.

Closes Favourorg#1155
PR Favourorg#1049 bumped react to 19.2.8 but left react-dom pinned to 19.2.7,
which React now hard-errors on at runtime ("Incompatible React versions"),
breaking the entire frontend test suite and blocking the pre-push hook.

Copy link
Copy Markdown
Owner Author

Closing — opened against the wrong repo (this fork instead of upstream Favourorg/Stellar-forge). Reopening correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Any authenticated wallet can unpin any user's IPFS metadata (IDOR)

1 participant