The Fix for CVE-2026-11960 is small enough to read in minutes, but the design lesson is broad. FacturaScripts 2025.61 exposed whether a username existed through differences in login responses. The upstream patch uses generic messages and a fixed dummy bcrypt hash to remove both obvious text branches and a timing asymmetry.

INCIBE rates the vulnerability CVSS v4.0 6.9 and reports no observed exploitation. The flaw is an information leak that can support later password attacks or social engineering. It is a useful case for developers because a neutral authentication error is not just a string. It is a combination of status, content, redirects, timing and side effects.

Start with the failure states

Write down every authentication outcome the client can reach: unknown user, disabled account, wrong password, required second factor, expired challenge, rate-limited request and recovery failure. For each one, define the status code, response body, headers, redirect and timing expectations.

Find branches that reveal whether the username exists. A message such as "user not found" is easy to spot. A missing account that skips password verification is harder to see in a page but can appear in response time. A proxy can add another branch when it limits repeated attempts.

The upstream FacturaScripts fix changes login, password-change and two-factor paths together. That scope matters: a login page can be corrected while a secondary form still says whether the same account exists.

Make the work comparable

One strategy is to perform the same expensive authentication check even when the account is missing. The FacturaScripts patch uses a fixed bcrypt hash and password_verify to provide that behavior. The dummy hash must never match a real password and should be treated as a fixed implementation constant under code review.

Another strategy is to defer the final failure until a common workflow step completes. That approach is harder to maintain when database calls, lockout logic and anti-automation checks differ by branch. A test should compare actual responses over repeated samples, not just inspect the source for a generic message.

Timing controls should not introduce a new observable state. A fixed sleep may waste capacity and still leave variation from earlier processing. A dummy hash is more closely tied to the work the valid-user path performs, but it is not a universal timing guarantee. Keep the model simple and measure it in the deployment environment.

Keep side effects consistent

Rate limits, account lockout counters, audit logs and password-reset state can reveal account existence even if the HTML is neutral. A login attempt for an unknown name should not bypass controls that would apply to a valid name in a way a client can observe. At the same time, counters must prevent an attacker from locking every plausible account with cheap requests.

The response to a lockout should be generic and should not say whether the submitted name was valid. Monitor the event internally with protected account identifiers so investigators can review it later. Do not echo usernames or account status into an error message, URL or response header.

Test the full path

Use an approved test account and a known nonexistent name. Repeat the same request through the actual proxy and network path. Compare status, body, redirect, headers and timing. Test the disabled and wrong-password cases separately, then test password change and second-factor validation.

A timing test needs many samples because network jitter can exceed the application difference. Run it under representative load and keep the results as a trend, not a single absolute threshold. The source patch is the primary fix; a test helps detect deployment drift.

Scope and external evidence

INCIBE identifies FacturaScripts 2025.61 as affected. A release containing commit ac32f1e2f5ca8b16b5c8f023a3d8824faa693155 is the direct code-level remediation to verify. The advisory does not establish a complete fixed-release list, so custom packages need provenance.

On October 29, 2026 in Beijing time, ZoomEye returned 104 assets for title="FacturaScripts" and 0 for vul.cve="CVE-2026-11960". The product count does not prove that those assets are vulnerable. It identifies candidate deployments for internal inventory and version checks.

ZoomEye FacturaScripts product search

Operational lessons

Authentication error handling is a security boundary. Review all user-visible responses and the work performed behind them. Make the same review part of upgrade testing and code review so a new message or early return does not reintroduce an enumeration channel.

Use rate limiting and monitoring as supporting controls. They can reduce the speed of username discovery and reveal follow-on guessing, but the application still needs neutral failures. Strong passwords and multi-factor authentication reduce the usefulness of any account list that is discovered.

For CVE-2026-11960, the immediate action is to verify the FacturaScripts fix. The longer-term lesson is to treat every authentication response as an observable interface, including the milliseconds and status codes that do not appear in the visible error text.

References