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

CVE-2026-78187: Piwigo XSS Vulnerability

CVE-2026-78187 is a cross-site scripting flaw in Piwigo 16.3.0 affecting the public authentication page. Attackers can exploit the lang parameter remotely. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-78187 Overview

CVE-2026-78187 is a reflected cross-site scripting (XSS) vulnerability in Piwigo 16.3.0, an open-source photo gallery application. The flaw resides in the Public Authentication Page, where the lang cookie parameter is echoed into an error message without proper HTML encoding. An attacker who can trick a user into setting a crafted lang cookie value can trigger script execution in the victim's browser session. The vulnerability is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation). Piwigo addressed the issue in version 16.4.0 via commit 5277a7dee4b8f1a174f1d69e1e2a4e1c82a3fc9e.

Critical Impact

Successful exploitation allows execution of attacker-controlled JavaScript in the context of the victim's Piwigo session, enabling limited integrity impact on the client side. Exploitation complexity is high and requires user interaction.

Affected Products

  • Piwigo 16.3.0
  • Piwigo versions prior to 16.4.0 that include the vulnerable identification.php cookie handling
  • Self-hosted Piwigo instances exposing the Public Authentication Page

Discovery Timeline

Technical Details for CVE-2026-78187

Vulnerability Analysis

The vulnerability is a reflected XSS flaw in Piwigo's authentication flow. When a request arrives at the login page, identification.php inspects the lang cookie. If the cookie value does not match a known language code, the application calls fatal_error() with an error message that concatenates the raw cookie contents. Because the cookie value is not passed through HTML encoding, an attacker-controlled payload is reflected verbatim into the response HTML. The result is script execution in the victim's browser under the origin of the Piwigo instance.

Exploitation requires user interaction, because the malicious lang cookie must be set in the victim's browser before they visit the authentication page. This dependency raises attack complexity but does not eliminate the risk in scenarios where an attacker can chain a cookie-set primitive or leverage a cross-site request from a controlled page.

Root Cause

The root cause is missing output encoding on the $_COOKIE['lang'] value in the fatal_error() call inside identification.php. The validation logic correctly rejects unknown language codes, but the rejection message inlines the untrusted cookie value into HTML output. This satisfies the classic [CWE-79] pattern: data flows from an untrusted source ($_COOKIE) into an HTML sink without sanitization.

Attack Vector

The attack vector is network-based and requires user interaction. An attacker crafts a page that sets the lang cookie for the Piwigo origin, or otherwise causes the victim's browser to carry a malicious lang cookie value. When the victim then loads the Public Authentication Page, Piwigo returns the fatal error page containing the reflected payload, and the browser executes the injected script.

php
// Patch: include/functions.inc.php - introduce load_cookie_language() and
// apply htmlspecialchars() to the reflected cookie value.
function load_cookie_language($load_language=true, $update_user=false, $unset_cookie=false, $user_id=null)
{
  global $user;

  // Load language if cookie is set from login/register/password pages
  if (isset($_COOKIE['lang']) and $user['language'] != $_COOKIE['lang'])
  {
    if (!array_key_exists($_COOKIE['lang'], get_languages()))
    {
      fatal_error('[Hacking attempt] the input parameter "'.htmlspecialchars($_COOKIE['lang']).'" is not valid');
    }

    $user['language'] = $_COOKIE['lang'];

    if ($update_user)
    {
      single_update(
        USER_INFOS_TABLE,
        array(
          'language' => $_COOKIE['lang']
        ),
        array(
          'user_id' => $user_id ?? $user['id']
        )
      );
    }
  }
}
// Source: https://github.com/Piwigo/Piwigo/commit/5277a7dee4b8f1a174f1d69e1e2a4e1c82a3fc9e

The patch wraps the reflected cookie value with htmlspecialchars(), neutralizing HTML metacharacters in the fatal error message. The refactor also centralizes cookie-language handling in a single function, replacing the inline logic previously present in identification.php. Additional details are available in the GitHub Reflected XSS PoC.

Detection Methods for CVE-2026-78187

Indicators of Compromise

  • Requests to the Piwigo authentication endpoint carrying a lang cookie value containing HTML metacharacters such as <, >, ", or script.
  • HTTP responses from Piwigo containing the string [Hacking attempt] the input parameter followed by unencoded HTML or JavaScript content.
  • Web server access logs showing repeated authentication page requests from a single client with varying lang cookie payloads.

Detection Strategies

  • Deploy Web Application Firewall (WAF) rules that inspect the lang cookie for HTML tag characters and script keywords on requests to Piwigo endpoints.
  • Add server-side logging around fatal_error() invocations in identification.php to capture rejected lang values for offline review.
  • Correlate browser-side Content Security Policy (CSP) violation reports with Piwigo origins to surface reflected script execution attempts.

Monitoring Recommendations

  • Monitor outbound requests from user browsers to unfamiliar domains immediately after visits to the Piwigo authentication page.
  • Track versions of deployed Piwigo instances and alert on any instance still reporting version 16.3.0 or earlier.
  • Review access logs weekly for anomalous Cookie: lang= headers containing URL-encoded HTML payloads.

How to Mitigate CVE-2026-78187

Immediate Actions Required

  • Upgrade all Piwigo instances to version 16.4.0 or later, which contains commit 5277a7dee4b8f1a174f1d69e1e2a4e1c82a3fc9e.
  • Audit existing Piwigo deployments for exposure and confirm that the Public Authentication Page is not reachable from untrusted networks where not required.
  • Rotate active session tokens and administrator credentials on any instance where suspicious lang cookie activity has been observed.

Patch Information

Piwigo released the fix in version 16.4.0. The corrective change is documented in commit 5277a7d and coordinated through GHSA-rr39-mf4j-6594. The patch applies htmlspecialchars() to the reflected lang cookie value and centralizes cookie-language handling in a new load_cookie_language() function inside include/functions.inc.php.

Workarounds

  • If immediate upgrade is not feasible, deploy a WAF rule that blocks or strips the lang cookie when it contains characters outside the expected language-code character set (letters, digits, hyphen, underscore).
  • Set a strict Content Security Policy on Piwigo responses that disallows inline scripts, reducing the impact of reflected payloads.
  • Restrict access to the Piwigo login page via network controls or authentication proxies until the upgrade is applied.
bash
# Example nginx snippet to strip suspicious lang cookies before they reach Piwigo
map $http_cookie $safe_cookie {
    default $http_cookie;
    "~*lang=[^;]*[<>\"'()]" "";
}

server {
    location /identification.php {
        proxy_set_header Cookie $safe_cookie;
        proxy_pass http://piwigo_backend;
    }
}

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

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

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.