Skip to content

[FIX] Klaviyo_Reclaim: Update Cart Controller#353

Open
tedsalmon wants to merge 2 commits intoklaviyo:masterfrom
tedsalmon:bugfix/support-unmasked-quote-ids
Open

[FIX] Klaviyo_Reclaim: Update Cart Controller#353
tedsalmon wants to merge 2 commits intoklaviyo:masterfrom
tedsalmon:bugfix/support-unmasked-quote-ids

Conversation

@tedsalmon
Copy link
Copy Markdown

Description

Adds support for unmasked quote IDs since logged in carts are not assigned a masked quote ID.

Manual Testing Steps

  1. Log in
  2. Create a cart
  3. Leave the store
  4. Wait for the email to come in
  5. Check the URI to ensure it is using an unmasked quote_id
  6. Ensure the cart reloads

Pre-Submission Checklist:

  • [X ] You've updated the CHANGELOG following the steps here

* Add support for unmasked quote IDs since logged in carts are not assigned a masked quote ID
@tedsalmon tedsalmon requested a review from a team as a code owner December 16, 2025 18:46
@klaviyoit klaviyoit requested a review from zchenk December 16, 2025 18:46
->load($quoteId, 'masked_id');
$quoteId = $quoteIdMask->getQuoteId();
}
$quote = $this->quoteRepository->get($quoteId);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Unmasked quote IDs allow unauthorized cart access via enumeration

The new code accepts numeric (unmasked) quote IDs directly without verifying that the quote belongs to the current user. Since Magento quote IDs are simple auto-incrementing integers, an attacker could enumerate quote IDs (e.g., quote_id=1, quote_id=2, etc.) to load other users' carts into their session. Masked quote IDs exist specifically to prevent this IDOR vulnerability. The code lacks ownership verification when processing numeric IDs, allowing potential unauthorized access to any user's cart.

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Author

@tedsalmon tedsalmon Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor is right, but if we added session validation, then reclaim would no longer work for users after their session expires. Perhaps a more meaningful fix can be added by the Klaviyo team by encrypting the quoe_id using the kx_identifier on their end.

Another possibility I thought about was forcing all quotes to have a masked_id generated at creation time, but I was not thrilled about modifying core functionality.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm with Cursor as well. We will evaluate safer options.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zchenk

FWIW, my second commit adds a check to ensure the logged in customer owns the quote

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tedsalmon thanks for submitting - i'll flag to the team to discuss after the holidays!

Comment thread Controller/Checkout/Cart.php Outdated
* Make sure that the customer owns the quote being loaded. This only applies to quotes for customers who are not logged in

 This is the commit message klaviyo#2:
@tedsalmon tedsalmon force-pushed the bugfix/support-unmasked-quote-ids branch from 94719d3 to 0191418 Compare December 16, 2025 20:28
Copy link
Copy Markdown

@zchenk zchenk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More internal discussions needed.

->load($quoteId, 'masked_id');
$quoteId = $quoteIdMask->getQuoteId();
}
$quote = $this->quoteRepository->get($quoteId);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm with Cursor as well. We will evaluate safer options.

@cykolln
Copy link
Copy Markdown
Contributor

cykolln commented Jan 29, 2026

@tedsalmon I'm having a hard time testing this, there arent any cases I'm seeing where a logged in user doesn't have a quote id that is formatted as kx_identifier_XX - can you provide more specific examples or steps to recreate?

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.

3 participants