Skip to content

Only a wishlist's owner may edit it - #6

Merged
loevgaard merged 1 commit into
masterfrom
fix-edit-any-wishlist
Jun 15, 2026
Merged

loevgaard merged 1 commit into
masterfrom
fix-edit-any-wishlist

Conversation

@loevgaard

@loevgaard loevgaard commented Jun 15, 2026 •

Copy link
Copy Markdown
Member

Fixes #3.

The problem

ShowWishlistAction (GET, PATCH /wishlists/{uuid}) loaded any wishlist by its UUID and persisted the
submitted WishlistType form (the wishlist name and each item's quantity) with no authorization
check
:

$wishlist = $this->wishlistRepository->findOneByUuid($uuid);   // any wishlist
$form = $this->formFactory->create(WishlistType::class, $wishlist);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
    $this->wishlistRepository->add($wishlist);                 // ← saved, no auth check
}

So anyone who knew or guessed a UUID could edit a wishlist they don't own. The other write paths were already
scoped correctly — AddToWishlistAction / RemoveFromWishlistAction only touch the current visitor's wishlists,
and RemoveWishlistItemAction already goes through WishlistVoter.

The fix

Gate the save behind the existing WishlistVoter (wishlist_edit), which grants access only when the wishlist
belongs to the current visitor:

if (!$this->authorizationChecker->isGranted(WishlistVoter::EDIT, $wishlist)) {
    throw new NotFoundHttpException(sprintf('Wishlist with id %s not found', $uuid));
}
  • Reads stay public. Only the form save is gated, so a wishlist can still be viewed (and shared) via its
    UUID URL.
  • No information disclosure. It returns 404 rather than 403, so you can't probe which UUIDs exist.
  • Uses AuthorizationCheckerInterface (the focused dependency for isGranted).

Tests

Adds ShowWishlistActionTest covering: owner save succeeds, non-owner save is refused, and a non-submitted
request neither authorizes nor saves.

Note

The plugin is still in alpha, so this PR also removes the Backwards Compatibility Check workflow rather than
shaping the code around BC (e.g. forcing the new dependency to be an optional constructor argument). It can be
restored when the API stabilises.

@codecov

codecov Bot commented Jun 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 36.49%. Comparing base (993ae9e) to head (76d037e).

Additional details and impacted files
@@             Coverage Diff              @@
##             master       #6      +/-   ##
============================================
+ Coverage     33.54%   36.49%   +2.95%     
- Complexity      161      162       +1     
============================================
  Files            36       36              
  Lines           483      485       +2     
============================================
+ Hits            162      177      +15     
+ Misses          321      308      -13     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loevgaard
loevgaard force-pushed the fix-edit-any-wishlist branch from 995497b to c20c3d0 Compare June 15, 2026 13:02
ShowWishlistAction persisted the submitted WishlistType form (name + item
quantities) for any wishlist addressed by its UUID, with no authorization
check, so anyone could edit a wishlist they don't own.

Gate the save behind the existing WishlistVoter (wishlist_edit) via the
AuthorizationCheckerInterface. Viewing a wishlist by its shareable URL stays
public, and a "not found" response (rather than "access denied") avoids
disclosing which wishlists exist.

The plugin is still in alpha, so also drop the backwards-compatibility-check
workflow rather than shaping the code around it.
@loevgaard
loevgaard force-pushed the fix-edit-any-wishlist branch from c20c3d0 to 76d037e Compare June 15, 2026 13:13
@loevgaard
loevgaard merged commit dc1b0c7 into master Jun 15, 2026
29 checks passed
@loevgaard
loevgaard deleted the fix-edit-any-wishlist branch June 15, 2026 13:32
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.

[Bug]: Security issues

1 participant