Skip to main content
Vulnerability Database/CVE-2026-77470

CVE-2026-77470: Lychee Photo Management Auth Bypass Flaw

CVE-2026-77470 is an authentication bypass vulnerability in Lychee photo-management tool that allows attackers to manipulate payment parameters and underpay for purchases. This article covers technical details, affected versions, impact, and mitigation strategies.

Published:

CVE-2026-77470 Overview

Lychee is a free, open-source photo-management tool with an optional Supporter and Pro webshop feature. CVE-2026-77470 is an input validation flaw ([CWE-20]) in the webshop checkout flow prior to version 7.7.1. The POST /api/v2/Shop/Checkout/Process endpoint accepts an unrestricted additional_data array that CheckoutService::preparePurchaseParameters() merges after server-computed purchase parameters. Because later string keys overwrite earlier keys in a PHP array_merge, an unauthenticated buyer can replace amount, currency, returnUrl, cancelUrl, or transactionId before the parameters reach a non-PayPal Omnipay gateway. The flaw is fixed in Lychee version 7.7.1.

Critical Impact

An unauthenticated attacker can underpay for digital goods by overriding server-set checkout parameters, obtaining auto-fulfilled items while the merchant receives an attacker-chosen amount.

Affected Products

  • Lychee photo-management application versions prior to 7.7.1
  • Supporter and Pro webshop deployments with the shop feature enabled
  • Installations configured with a non-PayPal Omnipay payment gateway

Discovery Timeline

  • 2026-10-15 - CVE CVE-2026-77470 published to NVD
  • 2026-10-15 - Last updated in NVD database

Technical Details for CVE-2026-77470

Vulnerability Analysis

The vulnerability is a business-logic parameter pollution flaw in the Lychee webshop checkout service. When a buyer submits a purchase request to POST /api/v2/Shop/Checkout/Process, the application accepts a user-controlled additional_data array alongside the standard checkout payload. The CheckoutService::preparePurchaseParameters() method constructs server-trusted purchase parameters, then merges the attacker-supplied data on top of them. Control over amount and currency lets an attacker purchase goods for a fraction of the listed price, while control over returnUrl and cancelUrl enables redirect abuse. Manipulation of transactionId can break order correlation and complicate fraud investigation.

Root Cause

The root cause is unsafe use of PHP array_merge() on untrusted input. In PHP, array_merge($params, $additional_data) causes later string keys to overwrite earlier ones. Because $additional_data originated from the HTTP request body with no key allow-list or sanitization, any key present in the server-generated $params could be silently replaced. The service applied no schema validation, no key filtering, and no price verification before passing the merged payload to CheckoutService::processPayment().

Attack Vector

Exploitation requires a reachable Lychee instance with the webshop enabled, at least one purchasable item, and a non-PayPal Omnipay gateway configured. The attacker does not need authentication. The attacker submits a crafted checkout request that includes an additional_data object with overriding keys such as amount set to a low value. The gateway then processes the modified transaction and the auto-fulfillment logic releases the purchased asset to the buyer.

php
// Patched code in app/Actions/Shop/CheckoutService.php (Lychee 7.7.1)
$params['name'] = $order->user->name;

// Remove any keys from $additional_data that are already in $params
// This ensures that $additional_data does not overwrite existing keys in $params
// Fixes that sneaky @5ud0er ;p
$param_keys = array_keys($params);
foreach ($param_keys as $key) {
    if (array_key_exists($key, $additional_data)) {
        unset($additional_data[$key]);
    }
}

// Merge any additional data
// We could flip the order of the merge, but we want to make sure that the
// additional data does not overwrite existing keys in $params
// Better be clear than trying to be smart.
return array_merge($params, $additional_data);

Source: GitHub Commit 24e6e11

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 Attacks

Detection Methods for CVE-2026-77470

Indicators of Compromise

  • Requests to /api/v2/Shop/Checkout/Process whose JSON body contains an additional_data object with keys named amount, currency, returnUrl, cancelUrl, or transactionId.
  • Omnipay gateway transactions whose captured amount is lower than the catalog price of the fulfilled item.
  • Order records where the stored transactionId does not match any value issued by the server-side order creation path.

Detection Strategies

  • Inspect application and reverse-proxy logs for POST requests to the checkout endpoint containing an additional_data field, and alert when server-computed parameter keys appear inside it.
  • Reconcile Omnipay gateway settlement reports against Lychee order totals and flag any mismatch between item price and captured amount.
  • Review auto-fulfilled download events that correlate to orders with unusually low transaction values.

Monitoring Recommendations

  • Enable verbose logging on CheckoutService::preparePurchaseParameters() and CheckoutService::processPayment() to capture the final merged parameter set.
  • Monitor outbound redirects from the shop flow for unexpected returnUrl or cancelUrl values pointing to attacker-controlled domains.
  • Alert on repeated checkout attempts from the same IP range that produce successful low-value settlements.

How to Mitigate CVE-2026-77470

Immediate Actions Required

  • Upgrade Lychee to version 7.7.1 or later, which removes conflicting keys from additional_data before merging into the server-trusted parameter set.
  • If immediate patching is not possible, disable the webshop feature or remove all purchasable items until the upgrade is complete.
  • Audit recent orders processed through non-PayPal Omnipay gateways and reconcile captured amounts against listed item prices.

Patch Information

The fix is delivered in Lychee Release v7.7.1 via GitHub Pull Request #4514. The patch modifies app/Actions/Shop/CheckoutService.php to unset any additional_data keys that already exist in the server-generated $params array before calling array_merge(). Full technical context is available in GitHub Security Advisory GHSA-476v-jr53-8rxc.

Workarounds

  • Temporarily disable the webshop module in the Lychee admin settings until the 7.7.1 upgrade is applied.
  • Switch the configured payment gateway to PayPal, which is not affected by this specific merge path, as a short-term containment step.
  • Place a reverse-proxy or WAF rule in front of /api/v2/Shop/Checkout/Process that strips the additional_data field from incoming request bodies.
bash
# Example nginx rule to drop requests carrying additional_data on checkout
location = /api/v2/Shop/Checkout/Process {
    if ($request_body ~* "additional_data") {
        return 400;
    }
    proxy_pass http://lychee_backend;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.