CVE-2026-67581 Overview
CVE-2026-67581 is an authentication bypass by capture-replay vulnerability in ZenHive mpp, an Elixir library that implements HTTP 402 payment-required flows backed by on-chain transfers. The flaw allows an unauthenticated remote client to obtain paid resources by resubmitting a single settled on-chain transfer credential. The MPP.Methods.EVM.verify/2 function matches transfers purely on token, recipient, and amount, without binding the proof to the current challenge or tracking prior use. Any historical transfer readable from a public block explorer satisfies later charges on static-price routes. This issue affects mpp from version 0.3.0 before 0.6.3, and is categorized under CWE-294: Authentication Bypass by Capture-replay.
Critical Impact
A remote unauthenticated attacker can bypass paid-content gating by replaying any matching on-chain transfer read from a public block explorer.
Affected Products
- ZenHive mpp version 0.3.0 and later
- ZenHive mpp versions before 0.6.3
- Elixir applications integrating MPP.Plug with MPP.Methods.EVM.verify/2
Discovery Timeline
- 2026-08-19 - CVE-2026-67581 published to NVD
- 2026-08-20 - Last updated in NVD database
Technical Details for CVE-2026-67581
Vulnerability Analysis
The vulnerability resides in the payment verification pipeline of the mpp library. When a client requests a paid resource, the server returns an HTTP 402 response carrying a challenge.id. The client is expected to provide a transaction-hash credential proving payment. The MPP.Methods.EVM.verify/2 function inspects the on-chain transfer and confirms only that the token address and destination match for ERC-20 payments, or that the destination and native value match for native transfers.
The verification routine never binds the proof to the specific challenge issued. The MPP.Plug deduplication store keys entries on challenge.id, but that identifier is regenerated for every new 402 response. A single settled transfer therefore satisfies an unbounded number of future charges on any static-price route. Attackers can source valid transaction hashes directly from public block explorers, requiring no interaction with legitimate users.
Root Cause
The root cause is missing binding between the payment proof and both the challenge context and prior-use state. Dedup keys tied to ephemeral challenge.id values cannot function as replay protection because a new key is minted per response. The verification predicate lacks nonce validation, single-use enforcement, and payer identity binding.
Attack Vector
Exploitation is remote, network-based, and requires no authentication or user interaction. An attacker enumerates transfers on the target's payment address using a public block explorer. They identify any transfer whose token, to, and amount (or to and value for native transfers) match the target route's static price. The attacker submits that transaction hash as the credential to each 402 challenge. Because verification does not bind the proof to challenge.id or record consumption, the server grants access repeatedly. See the GitHub Security Advisory GHSA-vp5h-xh25-44wf for additional context.
Detection Methods for CVE-2026-67581
Indicators of Compromise
- Multiple successful payment verifications referencing the same on-chain transaction hash across distinct challenge.id values.
- Payment proofs whose transaction timestamps predate the corresponding HTTP 402 challenge issuance time.
- Access to paid resources originating from client IPs that have no associated wallet or transfer history with the service.
Detection Strategies
- Correlate application logs to identify reuse of the same tx_hash across independent request sessions.
- Compare the on-chain block timestamp of each submitted transfer against the server-side challenge issuance time; flag proofs older than the challenge.
- Alert when the count of unique successful verifications for a given transaction hash exceeds one on any static-price route.
Monitoring Recommendations
- Log every MPP.Methods.EVM.verify/2 outcome with the submitted tx_hash, requester identity, challenge.id, and route.
- Ship verification and access logs to a centralized platform such as Singularity Data Lake for cross-request analytics and long-window replay detection.
- Monitor unusual growth in paid-route access without corresponding new on-chain transfers to the payment address.
How to Mitigate CVE-2026-67581
Immediate Actions Required
- Upgrade mpp to version 0.6.3 or later on all affected services.
- Audit application logs for reused transaction hashes across challenge.id values and revoke access granted through replayed proofs.
- Rotate payment-receiving addresses if historical transfers have been exposed and cannot be excluded from future verification windows.
Patch Information
The fix is available in mpp0.6.3. Review the upstream fix in the GitHub commit ecc0380 and cross-reference the OSV entry EEF-CVE-2026-67581 and CNA advisory for CVE-2026-67581. The patch binds payment proofs to challenge context and records prior consumption to prevent replay.
Workarounds
- Persist consumed transaction hashes in a durable store and reject any previously seen tx_hash regardless of challenge.id.
- Require that submitted transfers occur after the challenge issuance timestamp by comparing on-chain block time to the issued nonce time.
- Rotate the payment-receiving address per challenge or per session so historical transfers cannot satisfy future charges.
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

