CVE-2026-23997: 
PHP vulnerability analysis and mitigation

Overview

CVE-2026-23997 is a Stored Cross-Site Scripting (XSS) vulnerability in FacturaScripts, an open-source accounting and ERP application, affecting all versions up to and including 2025.71. The flaw exists in the "Observations" field of Delivery Notes, where historical data is rendered in the History view without proper HTML entity encoding, allowing injected JavaScript to execute in an administrator's browser session. Discovered and disclosed on February 2, 2026, the vulnerability was reported by researcher jaroslaw-wawiorko and published by NeoRazorX. The CVSS v3.1 base score is 8.0 (High) per the GitHub Advisory, though Feedly's aggregated data notes a score of 9.0 (Critical) with a changed scope (GitHub Advisory, NeoRazorX Advisory).

Technical details

The root cause is CWE-79 (Improper Neutralization of Input During Web Page Generation — Cross-site Scripting): the History view renders stored Observations field content without HTML entity encoding, allowing arbitrary JavaScript injection. An attacker with note-editing permissions (a low-privileged authenticated user) injects a malicious script into the Observations field of a Delivery Note; when an administrator later views the History tab for that record, the stored payload executes in the admin's browser session. The attack further exploits the absence of a "current password" verification requirement and bypasses CSRF protections during the password change API call, enabling full credential takeover via the injected script. The internal API structure needed to craft the password-change payload can be discovered by any legitimate user through browser developer tools, and the default admin username is commonly known (GitHub Advisory, NeoRazorX Advisory).

Impact

Successful exploitation results in a critical full account takeover of the FacturaScripts admin account, granting the attacker complete control over system management functions, sensitive financial data, and user configurations. Because the attack changes the admin password without requiring the current password and bypasses CSRF protections, the legitimate administrator is effectively locked out. The attacker gains access to all data managed by the ERP/accounting platform, including customer records, financial transactions, and system settings (GitHub Advisory, NeoRazorX Advisory).

Exploitability

A proof-of-concept exploit is publicly documented in the GitHub Security Advisory, detailing the exact steps to inject the payload and trigger admin password change via XSS (NeoRazorX Advisory). As of the time of disclosure, there is no confirmed evidence of in-the-wild exploitation, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. The EPSS score is approximately 0.014% (0.000140), indicating a currently low probability of active exploitation within 30 days (GitHub Advisory). No threat actor attribution has been reported.

Exploitation steps

  1. Reconnaissance: Log in to the FacturaScripts instance as a low-privileged user with note-editing permissions. Use browser developer tools to inspect the internal API structure for the password change endpoint, including required field names and values. Note the default admin username (commonly "admin").
  2. Craft malicious payload: Prepare a JavaScript payload that, when executed in the admin's browser, silently sends an API request to change the admin password. The payload should use fetch() or XMLHttpRequest to call the password change endpoint with the new credentials, bypassing CSRF token requirements.
  3. Inject payload: Navigate to Sales → Customers → Delivery Notes. Open or create a Delivery Note, fill in the "Number 2" field, then enter the malicious JavaScript (e.g., <img src=x onerror="fetch('/api/change-password', {method:'POST', body:...})">) in the Observations field and save.
  4. Wait for admin interaction: The injected script is now stored in the History tab of that Delivery Note. When an administrator views the History tab, the onerror event (or equivalent) triggers, executing the JavaScript in the admin's authenticated browser session.
  5. Achieve account takeover: The script silently submits a password change request using the admin's active session, bypassing CSRF protections and the missing current-password verification. The admin password is changed to the attacker's chosen value, granting full system access (GitHub Advisory, NeoRazorX Advisory).

Indicators of compromise

  • Logs: Unexpected admin password change events in application audit logs, especially those not initiated by the admin user; HTTP POST requests to the password change API endpoint originating from an admin session shortly after viewing a Delivery Note History tab.
  • Application Behavior: Admin account locked out or credentials changed without the admin's knowledge; unusual login activity from unfamiliar IP addresses following a password change event.
  • Network: Outbound requests from the FacturaScripts server or admin browser session to unexpected external endpoints (if the XSS payload includes data exfiltration); repeated access to the History tab of specific Delivery Notes by the admin account.
  • File System / Database: Unexpected modifications to the admin user record in the FacturaScripts database, particularly changes to the password hash field with a recent timestamp not correlated to a legitimate admin action.
  • Content: Presence of HTML/JavaScript tags (e.g., <img, <script, onerror=) in the Observations field of Delivery Notes in the database (GitHub Advisory).

Mitigation and workarounds

The GitHub Advisory lists affected versions as ≤ 2025.71 with no patched version explicitly named at the time of publication; however, Feedly's patch details indicate that upgrading to version 2025.71 or later (the next release after the vulnerable range) is the recommended remediation (GitHub Advisory). As an immediate workaround, restrict note-editing permissions to only highly trusted users, and monitor admin account activity for unauthorized password changes. Additionally, review recent admin password change events and audit the Observations fields of existing Delivery Notes for suspicious JavaScript content. Implement proper HTML entity encoding in the History view as a code-level fix if a patched release is not yet available.

Community reactions

The vulnerability was shared on Bluesky by TheHackerWire shortly after disclosure, and was picked up by several vulnerability tracking platforms including Vulners, CVEFeed, and VulDB (GitHub Advisory). No significant vendor statements beyond the original advisory or notable independent researcher commentary have been identified at this time.

Additional resources


Source: This report was generated using AI

Related PHP vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-55224HIGH8.7
  • PHP logoPHP
  • mineadmin/mineadmin
NoYesSep 30, 2026
CVE-2026-103111HIGH7.6
  • MariaDB Server logoMariaDB Server
  • mariadb11.8-server
NoYesSep 30, 2026
GHSA-3q6v-r5mr-hxv8HIGH7.5
  • PHP logoPHP
  • league/commonmark
NoYesSep 30, 2026
GHSA-97jj-33gv-5xf9MEDIUM6.1
  • PHP logoPHP
  • league/commonmark
NoYesSep 30, 2026
CVE-2026-104181MEDIUM5.4
  • PHP logoPHP
  • filament/filament
NoYesOct 01, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management