facturascripts/facturascripts: PHP Object Injection via unserialize() of Request Data in WidgetSelect
What fixes it
- 2026.7facturascripts/facturascripts, composerGitHub
composer require "facturascripts/facturascripts:^2026.7"
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
Summary
In WidgetSelect::processFormData(), when a select field is declared multiple="true" and is not readonly, the raw POST value is passed directly to unserialize($value) with no allowed_classes filter. For multiple selects the browser sends an array which SubRequest::get() re-serialises, so the code calls unserialize() to reverse it; a scalar string is returned verbatim, allowing an attacker to submit a serialized object instead. Unserializing the autoloadable XLSXWriter object invokes its __destruct(), which calls @unlink() on each attacker-set path in the protected $temp_files, giving arbitrary file deletion.
Details
Core/Lib/Widget/WidgetSelect.php:144(sink:implode(',', unserialize($value)))Core/Internal/SubRequest.php(SubRequest::get()returns the raw request value unsanitised)vendor/mk-j/php_xlsxwriter/xlsxwriter.class.php(gadget:XLSXWriter::__destruct()unlinks each entry of its protected$temp_files)
Proof of concept
- Authenticate and open an edit form that has a select field named
targetfielddeclaredmultiple="true". - Submit
targetfieldas a single string (not an array) set to a serializedXLSXWriterobject whose protectedtemp_filesholds the absolute path(s) to delete:
O:10:"XLSXWriter":1:{s:13:"\0*\0temp_files";a:1:{i:0;s:LEN:"<abs path>";}}- Save the form.
unserialize()builds the object and__destruct()deletes the target file(s).
Confirmed output:
BEFORE: -rw-r--r-- ... CANARY_victim_config.txt
PHP Fatal error: Uncaught TypeError: implode(): Argument #2 ... XLSXWriter given
in .../WidgetSelect.php:144
AFTER: ls: cannot access '.../CANARY_victim_config.txt': No such file or directory
Control: submitting a normal array ['a','b'] returns "a,b" and deletes nothing.
Reproduced 2x, deterministic.Impact
Any authenticated user whose session reaches an edit form containing a multiple="true" select can delete arbitrary files writable by the web-server user, with no admin privilege required. Deleting config.php reverts the ERP to its installer (denial of service and re-install hijack); deleting MyFiles/ or backups destroys invoices and attachments. The underlying unserialize() with no class filter is a PHP Object Injection primitive, reachable with any autoloadable gadget present on the server.
Credits
Discovered by Alisher Qarshibayev and reported through VulnCheck.
Text from GitHub Advisory Database
Affected versions 1
- facturascripts/facturascripts, composer>= 2025.7, <= 2026.65GitHub