CVE-2026-78655
Punk::Plugin::TOTP versions before 0.05 for Perl allow the second-factor attempt limit to be reset by replaying an earlier session cookie because the challenge route counts failures in the session
Punk::Plugin::TOTP versions before 0.05 for Perl allow the second-factor attempt limit to be reset by replaying an earlier session cookie because the challenge route counts failures in the session.
The POST handler on challenge_path keeps the failure count as tries inside the totp_pending record in the session, raising it on each rejected code and deleting the pending record once it reaches attempts, five by default. Punk::Session carries the session in a signed cookie unless the application declares a store, and keeps no server-side record, so an earlier value of the same session stays valid until the expiry stamped inside it. A client that saves the cookie before its failed attempts and presents it again gets the pending record back with its counter, and the limit never fires. The replayed record is accepted while its own expiry, pending_ttl seconds from the challenge and 300 by default, has not passed.
Sessions declared with a store are not affected: the pending record and its counter then live server-side.
The attempt limit does not bound guessing of the second factor, which is left to the per-address rate limit the plugin registers on the same path, 30 requests per 60 seconds.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
9.1
Punk::Plugin::TOTP versions before 0.05 for Perl allow the second-factor attempt limit to be reset by replaying an earlier session cookie because the challenge route counts failures in the session
Punk::Plugin::TOTP versions before 0.05 for Perl allow the second-factor attempt limit to be reset by replaying an earlier session cookie because the challenge route counts failures in the session.
The POST handler on challenge_path keeps the failure count as tries inside the totp_pending record in the session, raising it on each rejected code and deleting the pending record once it reaches attempts, five by default. Punk::Session carries the session in a signed cookie unless the application declares a store, and keeps no server-side record, so an earlier value of the same session stays valid until the expiry stamped inside it. A client that saves the cookie before its failed attempts and presents it again gets the pending record back with its counter, and the limit never fires. The replayed record is accepted while its own expiry, pending_ttl seconds from the challenge and 300 by default, has not passed.
Sessions declared with a store are not affected: the pending record and its counter then live server-side.
The attempt limit does not bound guessing of the second factor, which is left to the per-address rate limit the plugin registers on the same path, 30 requests per 60 seconds.
- Record
CVE-2026-78655- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-307, CWE-642
- Updated
- 2026-11-02
EUVDEUVD-2026-66120
9.1
Punk::Plugin::TOTP versions before 0.05 for Perl allow the second-factor attempt limit to be reset by replaying an earlier session cookie because the challenge route counts failures in the session.
The POST handler on challenge_path keeps the failure count as tries inside the totp_pending record in the session, raising it on each rejected code and deleting the pending record once it reaches attempts, five by default. Punk::Session carries the session in a signed cookie unless the application declares a store, and keeps no server-side record, so an earlier value of the same session stays valid until the expiry stamped inside it. A client that saves the cookie before its failed attempts and presents it again gets the pending record back with its counter, and the limit never fires. The replayed record is accepted while its own expiry, pending_ttl seconds from the challenge and 300 by default, has not passed.
Sessions declared with a store are not affected: the pending record and its counter then live server-side.
The attempt limit does not bound guessing of the second factor, which is left to the per-address rate limit the plugin registers on the same path, 30 requests per 60 seconds.
- Record
EUVD-2026-66120- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-vwg8-cr9j-895f
9.1
Punk::Plugin::TOTP versions before 0.05 for Perl allow the second-factor attempt limit to be...
Punk::Plugin::TOTP versions before 0.05 for Perl allow the second-factor attempt limit to be reset by replaying an earlier session cookie because the challenge route counts failures in the session.
The POST handler on challenge_path keeps the failure count as tries inside the totp_pending record in the session, raising it on each rejected code and deleting the pending record once it reaches attempts, five by default. Punk::Session carries the session in a signed cookie unless the application declares a store, and keeps no server-side record, so an earlier value of the same session stays valid until the expiry stamped inside it. A client that saves the cookie before its failed attempts and presents it again gets the pending record back with its counter, and the limit never fires. The replayed record is accepted while its own expiry, pending_ttl seconds from the challenge and 300 by default, has not passed.
Sessions declared with a store are not affected: the pending record and its counter then live server-side.
The attempt limit does not bound guessing of the second factor, which is left to the per-address rate limit the plugin registers on the same path, 30 requests per 60 seconds.
- Record
GHSA-vwg8-cr9j-895f- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-307
- Updated
- 2026-11-02
NVD
9.1
Punk::Plugin::TOTP versions before 0.05 for Perl allow the second-factor attempt limit to be reset by replaying an earlier session cookie because the challenge route counts failures in the session.
The POST handler on challenge_path keeps the failure count as tries inside the totp_pending record in the session, raising it on each rejected code and deleting the pending record once it reaches attempts, five by default. Punk::Session carries the session in a signed cookie unless the application declares a store, and keeps no server-side record, so an earlier value of the same session stays valid until the expiry stamped inside it. A client that saves the cookie before its failed attempts and presents it again gets the pending record back with its counter, and the limit never fires. The replayed record is accepted while its own expiry, pending_ttl seconds from the challenge and 300 by default, has not passed.
Sessions declared with a store are not affected: the pending record and its counter then live server-side.
The attempt limit does not bound guessing of the second factor, which is left to the per-address rate limit the plugin registers on the same path, 30 requests per 60 seconds.
- Record
CVE-2026-78655- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-307, CWE-642
- Updated
- 2026-11-02
History
| Recorded | Changed | Sources |
|---|---|---|
| aliases, published | EUVD | |
| first indexed | CVE List, GitHub Advisories, NVD |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-78655 is a critical vulnerability (CVSS 9.1), published August 25, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.50%, the 42nd percentile. No source names a fixed version.
References
metacpan.org/release/LNATION/Punk-TOTP-0.04/source/include/ptotp/ptotp_plugin.h
metacpan.org/release/LNATION/Punk-TOTP-0.04/view/lib/Punk/Plugin/TOTP.pm
metacpan.org/release/LNATION/Punk-0.32/view/lib/Punk/Session.pm
metacpan.org/release/LNATION/Punk-TOTP-0.05/source/Changes
openwall.com/lists/oss-security/2026/08/25/7
nvd.nist.gov/vuln/detail/CVE-2026-78655
github.com/advisories/GHSA-vwg8-cr9j-895f