Executive Summary
A second-order SQL injection vulnerability, tracked as CVE-2026-42324, has been disclosed in Piwigo, the open-source photo gallery application for the web. The flaw carries a CVSS score of 7.2 (High) and stems from admin/element_set_ranks.php, which stores administrator-controlled image_order[] values without enforcing Piwigo's existing sort-field whitelist. The unvalidated value is written directly into the image_order column of the categories table, and is later concatenated — unsanitized — into ORDER BY SQL clauses by several downstream files, including admin/batch_manager_global.php, admin/batch_manager_unit.php, include/section_init.inc.php, and include/ws_functions/pwg.categories.php.
Exploitation requires authenticated administrator access — this is not an unauthenticated, internet-facing attack path. However, because the malicious payload is stored and triggered on a later, separate request (the hallmark of a second-order injection), it can evade request-level input filtering and WAF rules that only inspect the initial write. Once triggered, an attacker with admin credentials can use UNION-based injection techniques to disclose sensitive database contents — including stored user credentials — or modify and delete data. The vulnerability affects all Piwigo releases ≤ 16.4.0 and is fixed in Piwigo 16.4.0.
Vulnerability Overview
| Attribute | Value |
|---|---|
| CVE ID | CVE-2026-42324 |
| CVSS Score | 7.2 (High) |
| Type | Second-Order SQL Injection (CWE-89) |
| Attack Vector | Network — via Piwigo admin panel (HTTP POST) |
| Privileges Required | Admin (authenticated administrator session) |
| User Interaction | None |
| Condition | At least one album containing at least one photo |
Affected Versions
| Product | Affected Versions | Fixed Version |
|---|---|---|
| Piwigo | ≤ 16.4.0 (prior to fix) | 16.4.0 |
Attack Vector
1. Attacker authenticates to Piwigo as an administrator (or hijacks/social-engineers
an existing admin session)
2. Attacker submits a POST request to admin/element_set_ranks.php with the
album sort mode set to "user_define" and a crafted image_order[] array value
3. element_set_ranks.php concatenates the submitted image_order[] entries
WITHOUT validating them against Piwigo's existing sort-field whitelist
4. The crafted expression is written verbatim into the image_order column
of the categories table via an UPDATE statement
5. On a LATER, separate request, the stored image_order value is read back
and concatenated directly into an ORDER BY clause by one of:
- admin/batch_manager_global.php
- admin/batch_manager_unit.php
- include/section_init.inc.php
- include/ws_functions/pwg.categories.php
6. The injected SQL executes in the context of that query (second-order
injection — payload storage and payload execution are decoupled)
7. Attacker leverages UNION-based injection to extract arbitrary table data,
including the user table (credentials, password hashes, session tokens)
8. Depending on database permissions, attacker may also modify or delete
records via the same injection pointImpact of Successful Exploitation
| Impact Area | Description |
|---|---|
| Data Exfiltration | UNION-based injection can dump arbitrary tables, including user accounts and password hashes |
| Database Compromise | Depending on DB user privileges, full read/write access to the underlying database |
| Data Integrity | Crafted queries can modify or delete album, photo, or user metadata |
| Privilege Escalation Risk | Exfiltrated credentials/hashes could be cracked or reused to escalate access elsewhere |
| Detection Evasion | Second-order nature means the malicious payload is stored on one request and fires on a later, unrelated request — bypassing filters that only inspect the initial input |
| Availability | Malformed or destructive injected queries can disrupt gallery/category browsing and Batch Manager operations |
Immediate Remediation
Step 1: Upgrade to Piwigo 16.4.0
# Back up the database and files before upgrading
mysqldump -u <user> -p <piwigo_db> > piwigo_backup_$(date +%F).sql
# Download and apply the 16.4.0 release (or use the built-in
# Piwigo auto-update feature from the admin dashboard)
# https://github.com/Piwigo/Piwigo/releases/tag/16.4.0Verify the running version afterward via Administration > General > Configuration or by checking include/constants.php for PHPWG_VERSION.
Step 2: Audit Existing Album Sort Values
After upgrading, review the image_order column in the categories table for any values that don't match Piwigo's legitimate sort-field syntax — these may indicate a payload was already stored prior to patching.
SELECT id, name, image_order FROM piwigo_categories
WHERE image_order IS NOT NULL;Reset any suspicious image_order values to NULL or a known-good default (e.g. rank ASC) and restart affected sessions.
Step 3: Harden Admin Access
Because exploitation requires an authenticated administrator account, reducing exposure of admin credentials materially reduces risk:
- Enforce strong, unique passwords and enable two-factor authentication for all administrator accounts
- Audit the admin user list and remove any stale or unnecessary administrator accounts
- Restrict access to
admin/paths at the web server or reverse proxy level to trusted IP ranges where feasible - Review recent admin activity and Batch Manager usage logs for unfamiliar sort-order configurations
If Immediate Patching Is Not Possible
- Restrict administrator panel access to a VPN or trusted network segment
- Monitor and alert on POST requests to
admin/element_set_ranks.php - Review database query logs for anomalous
ORDER BYclauses referencingUNION, subqueries, or unexpected column names - Apply a WAF rule flagging non-standard characters (
UNION,SELECT, comment sequences) inimage_order[]POST parameters as a stopgap — note this only mitigates the initial write, not the second-order trigger
Detection Indicators
| Indicator | Description |
|---|---|
POST requests to admin/element_set_ranks.php with unusual image_order[] values | Possible payload storage attempt |
categories.image_order values containing SQL keywords (UNION, SELECT, --, /*) | Stored injection payload |
Errors or anomalies from admin/batch_manager_global.php or admin/batch_manager_unit.php | Possible payload trigger/execution |
| Unexpected result sets or slow queries during category/album listing | Sign of an active UNION-based extraction |
| New or modified administrator accounts | Potential post-exploitation persistence |