TL;DR
Piwigo’sws_user_getListweb service concatenates themax_levelandmin_registerparameters into a SQL clause without any escaping. Anyone with a valid admin session—or an exposed API token—can pivot this bug into data leakage or privilege escalation. A one-line payload pulls the password hash of every user, and a full proof of concept is public.
1. Summary
| CVE ID | CVE-2024-43018 |
| Affected Product(s) | Piwigo ≤ 13.8.0 when the Admin “Users” page or its web-services endpoint is accessible |
| Volerion Risk Score | 7.8 / 10 |
| Exploit Status | Public PoC available |
| CISA KEV | No |
The bug is a straight-forward SQL injection reachable from the administration interface. Although it requires authentication, many sites expose Piwigo’s web-services API to external automation, and compromised low-privilege accounts can be escalated by stealing password hashes from higher-privilege users.
2. Context – Why a gallery software flaw matters
Piwigo powers photo galleries for small businesses, universities and municipalities because it is lightweight and PHP-only. Administrators often place the gallery on the same host that stores mail or CMS data. A SQL injection therefore threatens more than just the image catalog: in many cases the same MySQL instance backs WordPress or a ticketing system.
Piwigo also exposes a JSON-RPC style API designed for desktop upload tools. Once a helper application authenticates, it can call ws_user_getList programmatically. The vulnerable parameters live inside that API call, which means automation scripts and browser extensions are an additional attack surface.
3. Technical Details – Two unsanitised parameters, one dangerous query
ws_user_getList accepts several optional filters so admins can search for users by registration date or permission level. Internally the function builds an SQL string like this:
$where_clauses = array();
if (isset($params['min_register'])) {
$where_clauses[] = 'user_registration_date >= ' . $params['min_register'];
}
if (isset($params['max_level'])) {
$where_clauses[] = 'level <= ' . $params['max_level'];
}
$query = 'SELECT id, username, password FROM ' . USERS_TABLE .
($where_clauses ? ' WHERE ' . implode(' AND ', $where_clauses) : '');
Because $params['min_register'] and $params['max_level'] are concatenated verbatim, injecting a single quote closes the number literal and lets the attacker append arbitrary SQL:
min_register=0 OR 1=1# -> Dumps the whole table
max_level=0; UPDATE users SET level=9 WHERE id=1;# -> Privilege escalation
Proof of concept request
The following curl request returns every user record on a stock installation:
curl -k -X POST \
-d 'method=pwg.users.getList&max_level=0%20OR%201=1#' \
-d 'format=json' \
-d 'session_id=<your_admin_session_cookie>' \
https://<host>/ws.php
A vulnerable server responds with a full JSON array of user objects, including password hashes.
Why the original CVSS 9.1 applies
Although the attack requires an authenticated context, the default Piwigo role separation is weak and the injected query executes with database-root privileges (GRANT ALL ON piwigo.*). Confidentiality and integrity impacts are therefore both High, justifying the 9.1 base score.
4. Impact – From data leak to complete gallery takeover
An attacker who extracts password hashes can crack weaker ones offline and re-authenticate as the gallery owner. They can then:
- Disable hotlink protection or external watermarking, leading to copyright exposure.
- Edit plugin settings to inject PHP code via the template editor.
- Steal OAuth tokens stored in the
piwigo_configtable, which some organisations reuse across internal services.
In shared hosting environments the compromise extends to any application that uses the same MySQL credentials.
5. Remediation – How to close the hole
Upgrade to Piwigo 15.1.0 or later, where the maintainers replaced dynamic SQL with prepared statements and introduced a whitelist that restricts min_register and max_level to integer values.
If an immediate upgrade is not feasible:
- Place the
/admin.phpdirectory andws.phpendpoint behind HTTP Basic Auth or a VPN. - Deploy a web application firewall and block requests where
min_registerormax_levelcontain characters other than digits. - Ensure the MySQL user assigned to Piwigo has the least privileges necessary (
SELECT,INSERT,UPDATE,DELETEon the Piwigo schema only).
6. Timeline
| Date (UTC) | Milestone |
|---|---|
| 2025-07-29 20:15 | CVE-2024-43018 published on MITRE |
| 2025-07-29 20:18 | Volerion completes enrichment and releases risk score |
7. References
- GitHub issue with patch discussion: https://github.com/Piwigo/Piwigo/issues/2197
- Public proof of concept: https://github.com/joaosilva21/CVE-2024-43018
About Volerion
Volerion delivers AI-driven enrichment minutes after a CVE goes live. A single call to our REST API returns CVSS vectors, exploitability metrics and affected product information complete with remediation guidance. Our scoring model balances factors such as exploit maturity, prevalence and remediation effort to produce an actionable risk number.
How the Volerion Risk Score fits with CVSS and EPSS
At the time of writing:
- CVSS 3.1 rates this vulnerability 9.1, reflecting its high impact and ease of exploitation.
- EPSS currently assigns a probability of exploitation of 0.00 because the CVE is brand new and has little telemetry.
- Volerion’s composite Risk Score is 7.8, placing the flaw in our high-risk range because a working exploit already exists even though the attack surface is limited to authenticated contexts.