CVE-2026-77466 Overview
Lychee is a free, open-source photo-management tool with an optional webshop module. Versions prior to 7.7.0 allow a buyer to bypass payment validation by submitting the Omnipay Dummy test provider directly to the checkout endpoint. The CreateSessionRequest validator only checks that the submitted provider is a member of the OmnipayProviderType enum. It does not call OmnipayProviderType::isAllowed(), which filters out the hidden test gateway in production. The flaw lets a buyer complete a purchase flow without a real payment and, when auto-fulfill is enabled, triggers release of the purchasable item.
Critical Impact
Attackers can obtain purchasable webshop items without paying by routing checkout through the hidden Dummy test gateway.
Affected Products
- Lychee photo-management platform (webshop module)
- Lychee Supporter and Pro webshop tiers with an enabled purchasable item
- All versions prior to 7.7.0
Discovery Timeline
- 2026-10-15 - CVE-2026-77466 published to NVD
- 2026-10-15 - Last updated in NVD database
Technical Details for CVE-2026-77466
Vulnerability Analysis
The weakness is an input validation flaw [CWE-20] in the Lychee webshop checkout pipeline. Lychee exposes a list of supported Omnipay payment providers through OmnipayFactory::get_supported_providers(), which hides the Dummy test provider in production. The server-side request validator does not enforce the same allow-list.
An attacker submits a crafted checkout request that specifies Dummy as the provider. The request passes validation because Dummy is a legitimate member of the OmnipayProviderType enum. The checkout flow then proceeds through the dummy gateway, which always returns a successful payment status without charging the buyer. When webshop_auto_fulfill_enabled is set, OrderCompletedListener::fullfillOrder() releases the item to the buyer.
Guest buyers can trigger the flaw when webshop_allow_guest_checkout is enabled, removing any authentication prerequisite. The payment finalize status check is not the root cause; the gap sits in provider allow-listing at request validation time.
Root Cause
The validator in app/Http/Requests/Checkout/CreateSessionRequest.php and app/Http/Requests/Checkout/FinalizeRequest.php used Laravel's generic Illuminate\Validation\Rules\Enum rule against OmnipayProviderType. This rule accepts every enum case, including Dummy. The code never invokes OmnipayProviderType::isAllowed(), which is the method that excludes test-only providers in production builds.
Attack Vector
Exploitation is remote and unauthenticated when guest checkout is enabled. The attacker needs network access to a Lychee instance running the webshop module with at least one purchasable item configured. No user interaction from an administrator is required.
// Patch: app/Http/Requests/Checkout/CreateSessionRequest.php
use App\Enum\OmnipayProviderType;
use App\Http\Requests\BaseApiRequest;
use App\Http\Requests\Traits\HasBasketTrait;
-use Illuminate\Validation\Rules\Enum;
+use App\Rules\OmnipayProviderTypeRule;
class CreateSessionRequest extends BaseApiRequest implements HasBasket
{
Source: GitHub Commit 8b73656
// Patch: app/Http/Requests/Checkout/FinalizeRequest.php
use App\Enum\PaymentStatusType;
use App\Http\Requests\BaseApiRequest;
use App\Models\Order;
+use App\Rules\OmnipayProviderTypeRule;
use Illuminate\Database\Eloquent\ModelNotFoundException;
-use Illuminate\Validation\Rules\Enum;
Source: GitHub Commit 8b73656
The fix replaces the generic enum rule with a dedicated OmnipayProviderTypeRule that enforces isAllowed().
Detect Identity Attacks the Moment Authentication Fails
Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.
Stop Identity AttacksDetection Methods for CVE-2026-77466
Indicators of Compromise
- Checkout API requests containing the provider value Dummy sent to CreateSessionRequest or FinalizeRequest endpoints.
- Completed Order records with the Omnipay Dummy provider recorded against a non-zero line item.
- Fulfillment events emitted by OrderCompletedListener::fullfillOrder() with no corresponding gateway transaction identifier.
Detection Strategies
- Inspect webshop and web server logs for POST requests to the checkout session endpoint carrying a provider=Dummy parameter.
- Query the orders table for records where the payment provider column equals Dummy in production environments.
- Alert on fulfillment of purchasable items where the associated payment amount is zero or where the gateway reference is empty.
Monitoring Recommendations
- Enable application-level audit logging for the Lychee checkout and fulfillment flows and ship logs to a centralized SIEM.
- Monitor the Lychee release feed and GitHub security advisories, including GHSA-5wh2-hg7q-6hv3, for follow-up guidance.
- Review purchasable-item delivery events against gateway settlement reports on a recurring schedule.
How to Mitigate CVE-2026-77466
Immediate Actions Required
- Upgrade Lychee to version 7.7.0 or later, which replaces the enum rule with OmnipayProviderTypeRule enforcing isAllowed().
- Audit existing orders for completed transactions using the Dummy provider and reverse any fraudulent fulfillments.
- If an immediate upgrade is not possible, disable the webshop module or disable all purchasable items until the patch is applied.
Patch Information
The fix is shipped in Lychee Release v7.7.0 via Pull Request #4507 and commit 8b73656. Both CreateSessionRequest and FinalizeRequest now validate the provider through OmnipayProviderTypeRule, which calls OmnipayProviderType::isAllowed() and rejects the hidden Dummy test gateway in production.
Workarounds
- Set webshop_allow_guest_checkout to false to require authenticated accounts, raising the barrier for anonymous exploitation.
- Set webshop_auto_fulfill_enabled to false so item release requires manual review, breaking the automated fulfillment path.
- Temporarily disable all purchasable items in the webshop configuration until the host system is upgraded to 7.7.0.
# Upgrade Lychee to the patched release
git fetch --tags
git checkout v7.7.0
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

