CVE-2026-104905 Overview
CVE-2026-104905 is a PHP object injection vulnerability in FacturaScripts versions before 2026.7. The flaw resides in the WidgetSelect::processFormData() method, which calls unserialize() on raw POST data for multiple-select fields without specifying an allowed_classes filter. Authenticated attackers can submit a serialized XLSXWriter object as a field value to trigger its __destruct() method. The destructor deletes attacker-specified files such as config.php or backup data. The resulting file deletion causes denial of service and can enable application reinstallation hijack. This vulnerability is classified under [CWE-502: Deserialization of Untrusted Data].
Critical Impact
Authenticated attackers can delete arbitrary files on the server, including config.php, causing denial of service and potentially hijacking the application reinstall flow.
Affected Products
- FacturaScripts versions prior to 2026.7
- WidgetSelect component handling multiple-select form fields
- Deployments exposing authenticated form submission endpoints
Discovery Timeline
- 2026-10-05 - CVE-2026-104905 published to NVD
- 2026-10-06 - Last updated in NVD database
Technical Details for CVE-2026-104905
Vulnerability Analysis
The vulnerability occurs when FacturaScripts processes form submissions for widgets configured as multiple-select fields. The WidgetSelect::processFormData() method accepts raw POST input and passes it to PHP's unserialize() function without restricting which classes may be instantiated. An authenticated attacker can craft a serialized payload referencing any class present in the application's autoload scope. When PHP reconstructs the object and later invokes its __destruct() method, attacker-controlled logic executes within the application context. The XLSXWriter class exposes a destructor that removes files whose paths are stored in the object's properties.
Root Cause
The root cause is the absence of the allowed_classes option in the unserialize() call inside WidgetSelect::processFormData(). PHP has supported this filter since version 7.0 to prevent untrusted input from instantiating arbitrary classes. Without it, any class the application loads becomes a candidate gadget for property-oriented programming. The vulnerable code treats user-submitted field data as structured serialized input rather than scalar values.
Attack Vector
Exploitation requires an authenticated session with permission to submit a form containing a multiple-select widget. The attacker submits a POST request where the targeted field value is a PHP-serialized XLSXWriter object. The object's property containing a temporary file path is set to a sensitive application file such as config.php or a backup archive. When the request completes and the object is garbage collected, __destruct() deletes the specified file. Deleting config.php forces FacturaScripts into its installer, enabling an attacker to supply new database credentials and administrator accounts.
See the GitHub Security Advisory GHSA-p89j-gj6f-fh6g and the VulnCheck FacturaScripts Advisory for additional technical analysis.
Stop Remote Code Execution Before It Runs
Singularity™ Endpoint detects and blocks exploit attempts at machine speed, including zero-days and novel attack techniques.
Stop Exploit AttemptsDetection Methods for CVE-2026-104905
Indicators of Compromise
- Unexpected deletion of config.php, backup archives, or temporary export files in the FacturaScripts installation directory.
- POST requests to form submission endpoints where multiple-select field values begin with PHP serialization markers such as O:, a:, or s:.
- Application entering the installer or setup wizard outside of a planned deployment or upgrade window.
- Session logs showing low-privilege authenticated users submitting forms immediately before file loss events.
Detection Strategies
- Inspect web server access logs for POST bodies containing serialized object markers submitted to FacturaScripts endpoints handling WidgetSelect fields.
- Enable PHP error and audit logging to flag unserialize() operations that instantiate XLSXWriter or other destructor-bearing classes outside expected code paths.
- Correlate authenticated user actions with file system change events to identify destructive deserialization behavior.
Monitoring Recommendations
- Deploy file integrity monitoring on the FacturaScripts root directory, with alerts on changes to config.php, installation markers, and backup directories.
- Monitor for sudden transitions of the application into install or setup state via HTTP response patterns.
- Centralize PHP-FPM and web server logs for retrospective hunting of serialized payloads against form endpoints.
How to Mitigate CVE-2026-104905
Immediate Actions Required
- Upgrade FacturaScripts to version 2026.7 or later, which addresses the deserialization flaw.
- Restrict administrative panel access to trusted networks using a web application firewall or reverse proxy ACLs until patching is complete.
- Audit user accounts and revoke or rotate credentials for low-trust authenticated users on exposed instances.
- Back up config.php and database contents offline before applying updates so recovery is possible if files were already deleted.
Patch Information
The fix is included in FacturaScripts release v2026.7. The maintainer added an allowed_classes filter to the vulnerable unserialize() call, preventing arbitrary class instantiation from form input. Administrators should apply the upgrade through the standard FacturaScripts update mechanism or by replacing the application files with the released version.
Workarounds
- Place the FacturaScripts administrative interface behind VPN or IP allowlisting to reduce the authenticated attack surface.
- Enforce the principle of least privilege by limiting which user roles may submit forms that render WidgetSelect multiple-select fields.
- Set strict file system permissions so the PHP process user cannot delete config.php or backup files outside normal operations.
- Deploy WAF rules to block POST parameters containing PHP serialized object signatures such as O: or C: followed by class name declarations.
# Example WAF rule concept (ModSecurity) to block serialized PHP objects in POST data
SecRule REQUEST_METHOD "@streq POST" \
"id:1049051,phase:2,deny,status:403,msg:'Possible PHP object injection payload',\
chain"
SecRule ARGS "@rx O:[0-9]+:\"[A-Za-z_\\\\]+\":[0-9]+:\{" \
"t:none"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

