Skip to content

fix: enforce ownership on campaign update (IDOR)#26

Open
Adeolu01 wants to merge 1 commit into
OrbitChainLabs:mainfrom
Adeolu01:fix/campaign-update-broken-access-control
Open

fix: enforce ownership on campaign update (IDOR)#26
Adeolu01 wants to merge 1 commit into
OrbitChainLabs:mainfrom
Adeolu01:fix/campaign-update-broken-access-control

Conversation

@Adeolu01

Copy link
Copy Markdown
Contributor

Closes #19

CampaignsService.updateCampaign accepted a userId but never used it, so any authenticated wallet holder could overwrite the title, description, story, and imageUrl of every campaign — a textbook OWASP A01:2021 Broken Access Control / IDOR, with imageUrl/story usable for phishing injection and no audit trail.

Changes:

  • Enforce per-resource ownership in updateCampaign: reject with 403 Forbidden unless the caller is the campaign creator or an admin, mirroring the existing deleteUpdate admin-flag pattern.
  • Fix the controller passing the wrong identity (req.user.id, which is undefined) — now uses req.user.sub and derives isAdmin from req.user.role.
  • Write an AuditLog row (CAMPAIGN_UPDATED) on every successful update recording actor, target campaign, and the applied diff.
  • Add regression tests asserting 403 when wallet A edits a campaign owned by wallet B (including the coverImageUrl/phishing case), plus owner-success and admin-override coverage.

Note: @Roles('CREATOR','ADMIN') was intentionally not added to the route — campaign creation does not promote a USER to CREATOR, so that decorator would lock legitimate owners out of their own campaigns. Per-resource ownership is the correct boundary.

@Alqku

Alqku commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

@Adeolu01 please fix the CI thanks.

Alqku commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Clean, focused IDOR fix — the ownership check + audit log is exactly the right shape. Thanks for picking this up 🙌

Alqku commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Heads up: this now has a merge conflict on src/campaigns/campaigns.service.ts (and a couple of related files) after we landed #32. Could you rebase onto current main and push again? Once the conflict is resolved and CI is clean, I\u2019ll merge right away \u270d\ufe0f

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.

[CRITICAL] — PATCH /campaigns/:id is an IDOR: any authenticated wallet holder can overwrite *any* campaign's title, description, story, and image

2 participants