CVE-2026-49870 Overview
Snipe-IT is an open-source IT asset and license management system used to track hardware, software licenses, and consumables. CVE-2026-49870 affects Snipe-IT versions prior to 8.6.1, where the POST /two-factor endpoint enforces no rate limiting, lockout, or attempt counter. An attacker holding valid credentials can submit unlimited TOTP guesses against the three accepted codes generated by config/google2fa.php with window=1. A successful guess yields a fully authenticated session. Additional weaknesses allow disabling two-factor authentication through POST /account/profile with two_factor_optin=0 when two_factor_enabled is 1, and administrators can clear another user's secret via POST /api/v1/users/two_factor_reset. The issue is tracked under [CWE-770].
Critical Impact
An authenticated attacker can brute-force TOTP codes without restriction, defeating the second factor and achieving full session takeover on Snipe-IT deployments prior to 8.6.1.
Affected Products
- Snipe-IT versions prior to 8.6.1
- POST /two-factor endpoint (TOTP verification)
- POST /account/profile and POST /api/v1/users/two_factor_reset endpoints
Discovery Timeline
- 2026-08-19 - CVE-2026-49870 published to NVD
- 2026-08-19 - Last updated in NVD database
Technical Details for CVE-2026-49870
Vulnerability Analysis
The vulnerability is a missing rate-limit control on the TOTP verification route in Snipe-IT. The POST /two-factor handler accepts unlimited submissions of six-digit codes from an already password-authenticated session. Because config/google2fa.php sets window=1, three consecutive TOTP codes are accepted at any moment. An attacker can script sequential requests and reach a valid code in a bounded number of attempts. The successful response promotes the partially authenticated session into a fully authenticated one.
Two related weaknesses compound the impact. When two_factor_enabled equals 1, a user can submit POST /account/profile with two_factor_optin=0 and disable 2FA without providing a current OTP. Only required mode 2 prevents this opt-out. An administrator can also invoke POST /api/v1/users/two_factor_reset to clear another user's secret, enabling an insider to strip 2FA from any account.
Root Cause
The root cause is allocation of resources without limits [CWE-770]. The application registered a password_reset throttle but omitted an equivalent throttle for the two-factor verification route. Neither an attempt counter nor a lockout was applied to the authenticated session, so brute forcing the 10^6 keyspace against three accepted codes was computationally trivial.
Attack Vector
Exploitation requires valid credentials for a targeted account. The attacker authenticates with the primary password, obtains the pre-2FA session cookie, then repeatedly submits guessed TOTP codes to POST /two-factor until one of the three window-accepted codes is matched. The attack is network-reachable and does not require user interaction after credential compromise.
// Security patch in app/Providers/RouteServiceProvider.php - Throttle TOTP requests
return Limit::perMinute(config('auth.password_reset.max_attempts_per_min'))->by(optional($request->user())->id ?: $request->ip());
});
+ // Rate limiter for two-factor authentication — keyed on user ID since the user is already
+ // password-authenticated at this stage, preventing distributed brute force across IPs.
+ RateLimiter::for('two_factor', function (Request $request) {
+ return Limit::perMinute(config('auth.two_factor.max_attempts_per_min'))->by(optional($request->user())->id ?: $request->ip());
+ });
+
}
}
Source: GitHub Commit 46d5234
Detection Methods for CVE-2026-49870
Indicators of Compromise
- High volume of POST /two-factor requests from a single authenticated session or source IP within a short window.
- Authentication logs showing many failed TOTP attempts followed by a successful login for the same user.
- Unexpected POST /account/profile requests carrying two_factor_optin=0 for accounts that previously had 2FA enabled.
- Calls to POST /api/v1/users/two_factor_reset outside of documented administrator maintenance windows.
Detection Strategies
- Alert when the same user ID submits more than five TOTP verification requests per minute against /two-factor.
- Correlate 2FA state changes in the users table with the source request, flagging opt-outs that lack a preceding OTP challenge.
- Baseline administrative API usage and alert on two_factor_reset calls that deviate from the norm.
Monitoring Recommendations
- Forward Snipe-IT web server access logs and Laravel authentication logs to a centralized SIEM for correlation.
- Monitor session promotion events, comparing pre-2FA and post-2FA session identifiers to detect abnormal transitions.
- Track configuration drift on TWO_FACTOR_MAX_ATTEMPTS_PER_MIN and alert if the value is removed or raised above vendor guidance.
How to Mitigate CVE-2026-49870
Immediate Actions Required
- Upgrade Snipe-IT to version 8.6.1 or later, which introduces the two_factor rate limiter and closes the opt-out path.
- Rotate credentials for accounts that show anomalous TOTP submission patterns in historical logs.
- Enforce required mode 2 for two-factor authentication so users cannot self-disable 2FA through the profile endpoint.
- Restrict access to POST /api/v1/users/two_factor_reset to a minimal set of trusted administrators and audit its use.
Patch Information
The fix is available in Snipe-IT release v8.6.1. The patch adds a named two_factor rate limiter keyed on user ID, introduces the TWO_FACTOR_MAX_ATTEMPTS_PER_MIN environment variable (default 5), and hardens the 2FA opt-out flow. See the GitHub Security Advisory GHSA-mr8g-2mj4-pcq2 and Pull Request #19072 for details.
Workarounds
- Place Snipe-IT behind a reverse proxy or web application firewall and rate-limit POST /two-factor to a small number of requests per user session per minute.
- Temporarily disable the self-service 2FA opt-out flow by removing the profile form field or blocking two_factor_optin=0 submissions at the proxy.
- Revoke administrative privileges from accounts that do not require the two_factor_reset capability.
# Configuration example - set in Snipe-IT .env after upgrading to 8.6.1
PASSWORD_RESET_MAX_ATTEMPTS_PER_MIN=50
TWO_FACTOR_MAX_ATTEMPTS_PER_MIN=5
Source: GitHub Commit 46d5234
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

