{"api_version":"1","generated_at":"2026-10-01T09:45:19+00:00","cve":"CVE-2026-103651","urls":{"html":"https://cve.report/CVE-2026-103651","api":"https://cve.report/api/cve/CVE-2026-103651.json","docs":"https://cve.report/api","cve_org":"https://www.cve.org/CVERecord?id=CVE-2026-103651","nvd":"https://nvd.nist.gov/vuln/detail/CVE-2026-103651"},"summary":{"title":"MISP HOTP Token Replay via Stale Session-Cached Counter Allows Second-Factor Authentication Bypass","description":"MISP contains a vulnerability in its one-time password (OTP) authentication flow that allows replay of a consumed HOTP (paper) token and rewinding of the token counter.\n\nThe HOTP verification logic compared the submitted token against a counter value that was cached in the user's session at the time the password was entered, rather than against the authoritative counter stored in the database. Because the session-cached counter is not updated after a token is successfully consumed, an attacker who holds a valid session (password already submitted) can reuse a previously burned HOTP token. The stale cached counter still matches the replayed token, granting a second successful authentication and effectively rewinding the counter state.\n\nPreconditions:\n\n- The target user has HOTP (paper token) second-factor authentication enabled.\n\n- The attacker possesses a valid session in which the password step has already been completed (the OTP step is pending).\n\n- The attacker has access to at least one HOTP token value (e.g., a paper token list).\n\nSecurity impact:\n\n- Bypass of the second authentication factor, allowing unauthorized access to a user's MISP account.\n\n- Corruption of the HOTP counter state, potentially invalidating subsequent legitimate tokens or enabling further replays.\n\nAffected versions: <2.5.48.","state":"PUBLISHED","assigner":"CIRCL","published_at":"2026-10-01 08:16:51","updated_at":"2026-10-01 08:16:51"},"problem_types":["CWE-287","CWE-362","CWE-362 CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization (Race Condition)","CWE-287 CWE-287 Improper Authentication"],"metrics":[{"version":"4.0","source":"5a6e4751-2f3f-4070-9419-94fb35b644e8","type":"Secondary","score":"7.6","severity":"HIGH","vector":"CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","data":{"version":"4.0","vectorString":"CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","baseScore":7.6,"baseSeverity":"HIGH","attackVector":"NETWORK","attackComplexity":"HIGH","attackRequirements":"NONE","privilegesRequired":"LOW","userInteraction":"NONE","vulnConfidentialityImpact":"HIGH","vulnIntegrityImpact":"HIGH","vulnAvailabilityImpact":"NONE","subConfidentialityImpact":"NONE","subIntegrityImpact":"NONE","subAvailabilityImpact":"NONE","exploitMaturity":"NOT_DEFINED","confidentialityRequirement":"NOT_DEFINED","integrityRequirement":"NOT_DEFINED","availabilityRequirement":"NOT_DEFINED","modifiedAttackVector":"NOT_DEFINED","modifiedAttackComplexity":"NOT_DEFINED","modifiedAttackRequirements":"NOT_DEFINED","modifiedPrivilegesRequired":"NOT_DEFINED","modifiedUserInteraction":"NOT_DEFINED","modifiedVulnConfidentialityImpact":"NOT_DEFINED","modifiedVulnIntegrityImpact":"NOT_DEFINED","modifiedVulnAvailabilityImpact":"NOT_DEFINED","modifiedSubConfidentialityImpact":"NOT_DEFINED","modifiedSubIntegrityImpact":"NOT_DEFINED","modifiedSubAvailabilityImpact":"NOT_DEFINED","Safety":"NOT_DEFINED","Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","valueDensity":"NOT_DEFINED","vulnerabilityResponseEffort":"NOT_DEFINED","providerUrgency":"NOT_DEFINED"}},{"version":"4.0","source":"CNA","type":"CVSS","score":"7.6","severity":"HIGH","vector":"CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N","data":{"Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","Safety":"NOT_DEFINED","attackComplexity":"HIGH","attackRequirements":"NONE","attackVector":"NETWORK","baseScore":7.6,"baseSeverity":"HIGH","privilegesRequired":"LOW","providerUrgency":"NOT_DEFINED","subAvailabilityImpact":"NONE","subConfidentialityImpact":"NONE","subIntegrityImpact":"NONE","userInteraction":"NONE","valueDensity":"NOT_DEFINED","vectorString":"CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N","version":"4.0","vulnAvailabilityImpact":"NONE","vulnConfidentialityImpact":"HIGH","vulnIntegrityImpact":"HIGH","vulnerabilityResponseEffort":"NOT_DEFINED"}}],"references":[{"url":"https://github.com/MISP/MISP/commit/f34aee2c7","name":"https://github.com/MISP/MISP/commit/f34aee2c7","refsource":"5a6e4751-2f3f-4070-9419-94fb35b644e8","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-103651","name":"CVE Program record","refsource":"CVE.ORG","tags":["canonical"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-103651","name":"NVD vulnerability detail","refsource":"NVD","tags":["canonical","analysis"]}],"affected":[{"source":"CNA","vendor":"MISP","product":"MISP","version":"affected 2.5.48 semver","platforms":[]}],"timeline":[],"solutions":[{"source":"CNA","title":"","value":"The fix replaces the session-cached HOTP counter lookup with a direct read of the authoritative counter from the database, performed under a Redis-based distributed lock scoped to the user. The token is verified against the current stored counter, the counter is incremented and persisted atomically within the locked section, and the lock is released in a finally block. Additionally, the cached OTP user session entry is deleted immediately after a successful login (for both TOTP and HOTP paths), preventing the stale session state from being reused.","time":"","lang":"en"}],"workarounds":[],"exploits":[],"credits":[{"source":"CNA","value":"Tanguy Snoeck of NCIA","lang":"en"},{"source":"CNA","value":"iglocska","lang":"en"},{"source":"CNA","value":"Claude Opus 5.5 (1M context)","lang":"en"}],"nvd_cpes":[],"vendor_comments":[],"enrichments":{"kev":null,"epss":null,"legacy_qids":[]},"source_records":{"cve_program":{"containers":{"cna":{"affected":[{"cpes":["cpe:2.3:a:misp:misp:*:*:*:*:*:*:*:*"],"modules":["app/Controller/UsersController.php"],"product":"MISP","programFiles":["app/Controller/UsersController.php"],"repo":"https://github.com/MISP/MISP","vendor":"MISP","versions":[{"lessThan":"2.5.48","status":"affected","version":"0","versionType":"semver"}]}],"credits":[{"lang":"en","type":"reporter","value":"Tanguy Snoeck of NCIA"},{"lang":"en","type":"remediation developer","value":"iglocska"},{"lang":"en","type":"remediation developer","value":"Claude Opus 5.5 (1M context)"}],"descriptions":[{"lang":"en","supportingMedia":[{"base64":false,"type":"text/html","value":"<p>MISP contains a vulnerability in its one-time password (OTP) authentication flow that allows replay of a consumed HOTP (paper) token and rewinding of the token counter.</p><p>The HOTP verification logic compared the submitted token against a counter value that was cached in the user's session at the time the password was entered, rather than against the authoritative counter stored in the database. Because the session-cached counter is not updated after a token is successfully consumed, an attacker who holds a valid session (password already submitted) can reuse a previously burned HOTP token. The stale cached counter still matches the replayed token, granting a second successful authentication and effectively rewinding the counter state.</p><p>Preconditions:</p><p>- The target user has HOTP (paper token) second-factor authentication enabled.</p><p>- The attacker possesses a valid session in which the password step has already been completed (the OTP step is pending).</p><p>- The attacker has access to at least one HOTP token value (e.g., a paper token list).</p><p>Security impact:</p><p>- Bypass of the second authentication factor, allowing unauthorized access to a user's MISP account.</p><p>- Corruption of the HOTP counter state, potentially invalidating subsequent legitimate tokens or enabling further replays.</p><p>Affected versions: &lt;2.5.48.</p>"}],"value":"MISP contains a vulnerability in its one-time password (OTP) authentication flow that allows replay of a consumed HOTP (paper) token and rewinding of the token counter.\n\nThe HOTP verification logic compared the submitted token against a counter value that was cached in the user's session at the time the password was entered, rather than against the authoritative counter stored in the database. Because the session-cached counter is not updated after a token is successfully consumed, an attacker who holds a valid session (password already submitted) can reuse a previously burned HOTP token. The stale cached counter still matches the replayed token, granting a second successful authentication and effectively rewinding the counter state.\n\nPreconditions:\n\n- The target user has HOTP (paper token) second-factor authentication enabled.\n\n- The attacker possesses a valid session in which the password step has already been completed (the OTP step is pending).\n\n- The attacker has access to at least one HOTP token value (e.g., a paper token list).\n\nSecurity impact:\n\n- Bypass of the second authentication factor, allowing unauthorized access to a user's MISP account.\n\n- Corruption of the HOTP counter state, potentially invalidating subsequent legitimate tokens or enabling further replays.\n\nAffected versions: <2.5.48."}],"impacts":[{"capecId":"CAPEC-111","descriptions":[{"lang":"en","value":"CAPEC-111 Race Condition"}]}],"metrics":[{"cvssV4_0":{"Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","Safety":"NOT_DEFINED","attackComplexity":"HIGH","attackRequirements":"NONE","attackVector":"NETWORK","baseScore":7.6,"baseSeverity":"HIGH","privilegesRequired":"LOW","providerUrgency":"NOT_DEFINED","subAvailabilityImpact":"NONE","subConfidentialityImpact":"NONE","subIntegrityImpact":"NONE","userInteraction":"NONE","valueDensity":"NOT_DEFINED","vectorString":"CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N","version":"4.0","vulnAvailabilityImpact":"NONE","vulnConfidentialityImpact":"HIGH","vulnIntegrityImpact":"HIGH","vulnerabilityResponseEffort":"NOT_DEFINED"},"format":"CVSS","scenarios":[{"lang":"en","value":"GENERAL"}]},{"format":"SSVC","other":{"content":{"options":[{"Exploitation":"none"},{"Automatable":"no"},{"Technical Impact":"total"}],"role":"Supplier","timestamp":"2026-10-01T07:22:27Z","version":"2.0.3"},"type":"SSVC"},"scenarios":[{"lang":"en","value":"GENERAL"}]}],"problemTypes":[{"descriptions":[{"cweId":"CWE-362","description":"CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization (Race Condition)","lang":"en","type":"CWE"}]},{"descriptions":[{"cweId":"CWE-287","description":"CWE-287 Improper Authentication","lang":"en","type":"CWE"}]}],"providerMetadata":{"dateUpdated":"2026-10-01T07:34:02.597Z","orgId":"5a6e4751-2f3f-4070-9419-94fb35b644e8","shortName":"CIRCL"},"references":[{"name":"Security patch","tags":["patch"],"url":"https://github.com/MISP/MISP/commit/f34aee2c7"}],"solutions":[{"lang":"en","supportingMedia":[{"base64":false,"type":"text/html","value":"<p>The fix replaces the session-cached HOTP counter lookup with a direct read of the authoritative counter from the database, performed under a Redis-based distributed lock scoped to the user. The token is verified against the current stored counter, the counter is incremented and persisted atomically within the locked section, and the lock is released in a finally block. Additionally, the cached OTP user session entry is deleted immediately after a successful login (for both TOTP and HOTP paths), preventing the stale session state from being reused.</p>"}],"value":"The fix replaces the session-cached HOTP counter lookup with a direct read of the authoritative counter from the database, performed under a Redis-based distributed lock scoped to the user. The token is verified against the current stored counter, the counter is incremented and persisted atomically within the locked section, and the lock is released in a finally block. Additionally, the cached OTP user session entry is deleted immediately after a successful login (for both TOTP and HOTP paths), preventing the stale session state from being reused."}],"title":"MISP HOTP Token Replay via Stale Session-Cached Counter Allows Second-Factor Authentication Bypass","x_gcve":[{"extensions":{"bcp-05-x-01":{"ai_annotations":[{"ai_level":"generated","description":"Draft vulnerability metadata was generated from a git-format patch using an Ollama-hosted language model. Human validation is required before publication.","gna_source":1,"models":[{"gna_source":1,"identifier":"qwen3.8:27b","name":"qwen3.8:27b","source":"ollama"}],"review_status":"full","scope":"record","tags":["ai-computer-assisted:llm-generated","ai-computer-assisted:classification"]}]},"bcp-05-x-02":{"x_patch2vuln":{"assumptions":["The tag_version_boundary metadata (v2.5.48, 41 commits after fix) is interpreted as the first release containing the fix; no explicit fixed_version or affected_version was provided in the metadata.","The CAPEC-111 mapping is the closest available pattern; the vulnerability is specifically a stale-session-cache replay rather than a classic TOCTOU race, and no more precise CAPEC exists in the catalog.","CVSS PR:L assumes the attacker already has a valid authenticated session (password step completed); if the threat model requires unauthenticated access, PR would be None but AC would remain High.","The Redis lock is assumed to be available in the deployment; if Redis is not configured, the locking mechanism may be bypassed, though this is a deployment concern not reflected in the patch.","The Co-Authored-By line references an AI assistant; it is recorded as a tool credit rather than a human remediation developer."],"capecRationale":[{"capecId":"CAPEC-111","rationale":"The vulnerability is exploited by exploiting the time window between the session-cached counter being set (at password entry) and the token being consumed, allowing a replayed token to be validated against the stale value. CAPEC-111 (Race Condition) is the closest available CAPEC pattern; the attack is not a classic TOCTOU on a file or memory location but rather a stale-cache race on a shared counter, which falls under the broader race-condition category. No more specific CAPEC for session-cached credential state replay exists in the CAPEC catalog, so this is the best available match."}],"commit":"f34aee2c74e111fffd07e8ddde8e4843ccf998db","confidence":"medium","credits":[{"lang":"en","type":"reporter","value":"Tanguy Snoeck of NCIA"},{"lang":"en","type":"remediation developer","value":"iglocska"},{"lang":"en","type":"remediation developer","value":"Claude Opus 5.5 (1M context)"}],"cvssRationale":"AV:N – MISP is a network-accessible web application. AC:H – exploitation requires a valid session with the password step already completed, possession of a valid HOTP token value, and the session must still hold the stale cached counter; multiple preconditions must align. AT:N – no manipulation of the target system is needed. PR:L – the attacker must be an authenticated user with a pending OTP session. UI:N – no additional user interaction is required beyond the initial login flow. VC:H – successful exploitation grants full access to the target user's MISP account and its data. VI:H – the attacker can perform any action the user is authorized to perform, and the counter corruption may affect subsequent legitimate authentication. VA:N – no denial-of-service impact is evident. SC/SI/SA:N – no secondary system impact is indicated by the patch.","fixSummary":"The fix replaces the session-cached HOTP counter lookup with a direct read of the authoritative counter from the database, performed under a Redis-based distributed lock scoped to the user. The token is verified against the current stored counter, the counter is incremented and persisted atomically within the locked section, and the lock is released in a finally block. Additionally, the cached OTP user session entry is deleted immediately after a successful login (for both TOTP and HOTP paths), preventing the stale session state from being reused.","generatedAt":"2026-10-01T07:22:27.568266Z","generator":"patch2vuln.py","model":"qwen3.8:27b","modelComparison":{"rankings":[{"agreementScore":11,"assumptionCount":5,"confidence":"medium","model":"qwen3.8:27b","score":7}],"selectedModel":"qwen3.8:27b","selectionMethod":"deterministic-consensus-v1","selectionNotice":"The selected result is closest to model consensus; this heuristic does not establish factual correctness and human review remains required."},"patchSha256":"9ec05e4a3d95b183604c7e89e3fbb93950ac4d23dfe478809b868b6dfe85bad6","patchSummary":"In UsersController::otp(), the inline HOTP verification block (which used the session-cached $user['hotp_counter']) is replaced with a call to a new private method __consumeHotp(). This method acquires a Redis SETNX lock (misp:otp:hotp_lock:{userId}, 10 s TTL), re-fetches the user's totp secret and hotp_counter from the database, verifies the submitted OTP against the stored counter, increments and saves the counter, and releases the lock in a finally block. The otp_user session key is now deleted after both TOTP and HOTP successful login paths. Net change: +36 / -5 lines in app/Controller/UsersController.php.","patchTruncated":false,"patches":[{"commit":"f34aee2c74e111fffd07e8ddde8e4843ccf998db","date":"Wed, 23 Sep 2026 16:20:38 +0200","patchSha256":"9ec05e4a3d95b183604c7e89e3fbb93950ac4d23dfe478809b868b6dfe85bad6","source":"https://github.com/MISP/MISP/commit/f34aee2c7.patch","sourceUrl":"https://github.com/MISP/MISP/commit/f34aee2c7.patch","subject":"fix: [security] Burn paper OTP tokens against the stored"}],"source":"https://github.com/MISP/MISP/commit/f34aee2c7.patch","ssvc":{"options":[{"Exploitation":"none"},{"Automatable":"no"},{"Technical Impact":"total"}],"role":"Supplier","timestamp":"2026-10-01T07:22:27Z","version":"2.0.3"},"subject":"fix: [security] Burn paper OTP tokens against the stored","tagVersionBoundary":{"commits_after_fix":41,"repository":"https://github.com/MISP/MISP","tag":"v2.5.48","version":"2.5.48","version_type":"semver"},"weaknessRationale":[{"cweId":"CWE-362","rationale":"The HOTP counter is shared mutable state accessed without synchronization. The session-cached copy becomes stale relative to the database copy, and no lock is held during read-verify-increment, allowing a concurrent or replayed request to operate on the old value."},{"cweId":"CWE-287","rationale":"The OTP verification logic accepts a token that has already been consumed because it compares against a stale cached counter rather than the authoritative stored counter, effectively weakening the second-factor authentication check."}]}},"bcp-05-x-03":{"x_timeline":{"events":[{"description":"Corrective change authored (f34aee2c74e111fffd07e8ddde8e4843ccf998db): fix: [security] Burn paper OTP tokens against the stored","id":"evt-fix-developed-1","references":["https://github.com/MISP/MISP/commit/f34aee2c7.patch"],"timestamp":"2026-09-23T14:20:38Z","type":"fix-developed"}]}}},"recordType":"advisory","vulnId":"GCVE-1-2026-20307"}]}},"cveMetadata":{"assignerOrgId":"5a6e4751-2f3f-4070-9419-94fb35b644e8","assignerShortName":"CIRCL","cveId":"CVE-2026-103651","datePublished":"2026-10-01T07:34:02.597Z","dateReserved":"2026-10-01T07:34:00.794Z","dateUpdated":"2026-10-01T07:34:02.597Z","state":"PUBLISHED"},"dataType":"CVE_RECORD","dataVersion":"5.2"},"nvd":{"publishedDate":"2026-10-01 08:16:51","lastModifiedDate":"2026-10-01 08:16:51","problem_types":["CWE-287","CWE-362","CWE-362 CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization (Race Condition)","CWE-287 CWE-287 Improper Authentication"],"metrics":{"cvssMetricV40":[{"source":"5a6e4751-2f3f-4070-9419-94fb35b644e8","type":"Secondary","cvssData":{"version":"4.0","vectorString":"CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","baseScore":7.6,"baseSeverity":"HIGH","attackVector":"NETWORK","attackComplexity":"HIGH","attackRequirements":"NONE","privilegesRequired":"LOW","userInteraction":"NONE","vulnConfidentialityImpact":"HIGH","vulnIntegrityImpact":"HIGH","vulnAvailabilityImpact":"NONE","subConfidentialityImpact":"NONE","subIntegrityImpact":"NONE","subAvailabilityImpact":"NONE","exploitMaturity":"NOT_DEFINED","confidentialityRequirement":"NOT_DEFINED","integrityRequirement":"NOT_DEFINED","availabilityRequirement":"NOT_DEFINED","modifiedAttackVector":"NOT_DEFINED","modifiedAttackComplexity":"NOT_DEFINED","modifiedAttackRequirements":"NOT_DEFINED","modifiedPrivilegesRequired":"NOT_DEFINED","modifiedUserInteraction":"NOT_DEFINED","modifiedVulnConfidentialityImpact":"NOT_DEFINED","modifiedVulnIntegrityImpact":"NOT_DEFINED","modifiedVulnAvailabilityImpact":"NOT_DEFINED","modifiedSubConfidentialityImpact":"NOT_DEFINED","modifiedSubIntegrityImpact":"NOT_DEFINED","modifiedSubAvailabilityImpact":"NOT_DEFINED","Safety":"NOT_DEFINED","Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","valueDensity":"NOT_DEFINED","vulnerabilityResponseEffort":"NOT_DEFINED","providerUrgency":"NOT_DEFINED"}}],"ssvcV203":[{"source":"5a6e4751-2f3f-4070-9419-94fb35b644e8","ssvcData":{"timestamp":"2026-10-01T07:22:27Z","options":[{"exploitation":"none"},{"automatable":"no"},{"technicalImpact":"total"}],"role":"Supplier","version":"2.0.3"}}]},"configurations":[]},"legacy_mitre":{"record":{"CveYear":"2026","CveId":"103651","Ordinal":"1","Title":"MISP HOTP Token Replay via Stale Session-Cached Counter Allows S","CVE":"CVE-2026-103651","Year":"2026"},"notes":[{"CveYear":"2026","CveId":"103651","Ordinal":"1","NoteData":"MISP contains a vulnerability in its one-time password (OTP) authentication flow that allows replay of a consumed HOTP (paper) token and rewinding of the token counter.\n\nThe HOTP verification logic compared the submitted token against a counter value that was cached in the user's session at the time the password was entered, rather than against the authoritative counter stored in the database. Because the session-cached counter is not updated after a token is successfully consumed, an attacker who holds a valid session (password already submitted) can reuse a previously burned HOTP token. The stale cached counter still matches the replayed token, granting a second successful authentication and effectively rewinding the counter state.\n\nPreconditions:\n\n- The target user has HOTP (paper token) second-factor authentication enabled.\n\n- The attacker possesses a valid session in which the password step has already been completed (the OTP step is pending).\n\n- The attacker has access to at least one HOTP token value (e.g., a paper token list).\n\nSecurity impact:\n\n- Bypass of the second authentication factor, allowing unauthorized access to a user's MISP account.\n\n- Corruption of the HOTP counter state, potentially invalidating subsequent legitimate tokens or enabling further replays.\n\nAffected versions: <2.5.48.","Type":"Description","Title":"MISP HOTP Token Replay via Stale Session-Cached Counter Allows S"}]}}}