Skip to content

Security: enforce payment ownership in the status-polling AJAX endpoint#1372

Open
vuckro wants to merge 1 commit into
Ultimate-Multisite:mainfrom
vuckro:security/payment-status-ownership
Open

Security: enforce payment ownership in the status-polling AJAX endpoint#1372
vuckro wants to merge 1 commit into
Ultimate-Multisite:mainfrom
vuckro:security/payment-status-ownership

Conversation

@vuckro

@vuckro vuckro commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Gateway_Manager::ajax_check_payment_status() looked a payment up by its hash
and then disclosed its status and called the gateway's
verify_and_complete_payment() with no ownership check. The payment hash is
a reversible identifier, and the wu_payment_status_poll nonce is a single
static value localised into every checkout/thank-you page, so neither restricts
which payment a caller may target — any logged-in user could poll arbitrary
payments and trigger gateway verification on them (IDOR).

Changes

Require the current customer to own the payment (or be a network admin) before
proceeding, returning the same generic "not found" response on mismatch so the
endpoint doesn't reveal which payment ids exist.

Compatibility

The legitimate caller is the customer who just checked out, polling their own
payment — unaffected. No API/DB changes.


Part of a small series of focused security hardening PRs. Full technical detail
is available privately to the maintainers on request (coordinated disclosure).

Summary by CodeRabbit

  • Bug Fixes
    • Strengthened payment status verification with enhanced access control. The payment status endpoint now enforces user ownership validation, ensuring customers can only access their own payment information. Unauthorized requests receive appropriate error responses.

ajax_check_payment_status() looked a payment up by its hash and then
disclosed its status and called the gateway's verify_and_complete_payment()
with no ownership check. The payment hash is a reversible identifier and the
'wu_payment_status_poll' nonce is a single static value localised into every
checkout/thank-you page, so neither restricts which payment a caller may
target. Any logged-in user could therefore poll arbitrary payments and
trigger gateway verification on them.

Require the current customer to own the payment (or be a network admin)
before proceeding, returning the same generic "not found" response on
mismatch to avoid leaking which payment ids exist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9ce2f78-a3eb-4e34-8488-f39539d8a56d

📥 Commits

Reviewing files that changed from the base of the PR and between 1310078 and 61bacc8.

📒 Files selected for processing (1)
  • inc/managers/class-gateway-manager.php

📝 Walkthrough

Walkthrough

The pull request adds authorization enforcement to the payment status AJAX handler. After validating the nonce and loading the payment, the handler now retrieves the current customer and verifies ownership by comparing customer IDs. Unauthorized requests receive a "Payment not found" error response.

Changes

Payment Ownership Authorization

Layer / File(s) Summary
Payment ownership verification gate
inc/managers/class-gateway-manager.php
The ajax_check_payment_status() handler now enforces customer ownership by fetching the logged-in user, comparing the payment's customer ID, and denying access with "Payment not found" unless the user owns the payment or possesses manage_network capability.

🎯 2 (Simple) | ⏱️ ~12 minutes

A rabbit hops through the gate, 🐰
Checking who owns what they see,
Only rightful keepers pass,
Or those with the network key! 🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main security change: enforcing payment ownership validation in the status-polling AJAX endpoint, which matches the core objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

1 participant