{"schema":"threatline.record/2","record":{"id":"GHSA-p89j-gj6f-fh6g","aliases":["GHSA-p89j-gj6f-fh6g"],"summary":"PHP Object Injection via unserialize() of Request Data in WidgetSelect","details":"### Summary\r\n\r\nIn `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.\r\n\r\n### Details\r\n\r\n- `Core/Lib/Widget/WidgetSelect.php:144` (sink: `implode(',', unserialize($value))`)\r\n- `Core/Internal/SubRequest.php` (`SubRequest::get()` returns the raw request value unsanitised)\r\n- `vendor/mk-j/php_xlsxwriter/xlsxwriter.class.php` (gadget: `XLSXWriter::__destruct()` unlinks each entry of its protected `$temp_files`)\r\n\r\n### Proof of concept\r\n\r\n1. Authenticate and open an edit form that has a select field named `targetfield` declared `multiple=\"true\"`.\r\n2. Submit `targetfield` as a single string (not an array) set to a serialized `XLSXWriter` object whose protected `temp_files` holds the absolute path(s) to delete:\r\n\r\n   ```\r\n   O:10:\"XLSXWriter\":1:{s:13:\"\\0*\\0temp_files\";a:1:{i:0;s:LEN:\"<abs path>\";}}\r\n   ```\r\n\r\n3. Save the form. `unserialize()` builds the object and `__destruct()` deletes the target file(s).\r\n\r\nConfirmed output:\r\n\r\n```\r\nBEFORE: -rw-r--r-- ... CANARY_victim_config.txt\r\nPHP Fatal error: Uncaught TypeError: implode(): Argument #2 ... XLSXWriter given\r\n                 in .../WidgetSelect.php:144\r\nAFTER:  ls: cannot access '.../CANARY_victim_config.txt': No such file or directory\r\nControl: submitting a normal array ['a','b'] returns \"a,b\" and deletes nothing.\r\nReproduced 2x, deterministic.\r\n```\r\n\r\n### Impact\r\n\r\nAny 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.\r\n\r\n### Credits\r\n\r\nDiscovered by Alisher Qarshibayev and reported through VulnCheck.","categories":["Unclassified"],"product":"facturascripts/facturascripts","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/NeoRazorX/facturascripts/security/advisories/GHSA-p89j-gj6f-fh6g","source_modified_at":"2026-10-05T10:09:23Z","fetched_at":"2026-10-25T21:40:15.971031Z","package":{"ecosystem":"composer","name":"facturascripts/facturascripts"},"range":">= 2025.7, <= 2026.65"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/NeoRazorX/facturascripts/security/advisories/GHSA-p89j-gj6f-fh6g","source_modified_at":"2026-10-05T10:09:23Z","fetched_at":"2026-10-25T21:40:15.971031Z","package":{"ecosystem":"composer","name":"facturascripts/facturascripts"},"version":"2026.7"}],"cvss":6.1,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-05T10:09:23Z","modified_at":"2026-10-05T10:09:23Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/NeoRazorX/facturascripts/security/advisories/GHSA-p89j-gj6f-fh6g","fetched_at":"2026-10-25T21:40:15.971031Z","source_modified_at":"2026-10-05T10:09:23Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-10-05T10:09:23Z","content_hash":"287cd01933aae0822f51148a43fe6004701e065528146d07633d76ad3bb29767"}}
