CVE-2026-89420 in mpp
Summary
by MITRE • 09/22/2026
Improper Validation of Specified Quantity in Input in ZenHive mpp allows a client holding an open payment channel to obtain paid resources without being charged.
MPP.Session.Actions.accept_voucher/3 in lib/mpp/session/actions.ex treats a voucher whose cumulativeAmount equals the channel's already-accepted cumulative amount as an idempotent success, returning the channel unchanged without calling maybe_spend/2. The credential verifies, the protected resource is served, and spent and units stay where they were. Because the server issues a fresh challenge per request and the credential replay store keys on challenge id and payload, the same signed voucher can be re-presented under every new challenge, so one paid voucher yields an unbounded number of paid units. The path is reachable from any method built on MPP.Session.Method through the Plug, MCP, JSON-RPC and WebSocket transports.
This issue affects mpp: from 0.14.0 before 0.16.2.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 09/22/2026
The vulnerability identified in ZenHive's Multi-Path Payment (MPP) implementation represents a critical flaw in the validation logic governing voucher acceptance and resource consumption within payment channels. Specifically, the defect resides in the Mpp.Session.Actions.accept_voucher/3 function located in lib/mpp/session/actions.ex. This component is responsible for processing vouchers that clients present to access protected resources or services facilitated by the channel infrastructure. The core issue arises from an improper validation of specified quantities during this acceptance process, which fundamentally breaks the economic model and security guarantees expected of a payment channel system where resource consumption must be strictly tied to financial settlement.
The technical mechanism of the exploit relies on a specific edge case in how cumulative amounts are compared against existing state. When a client presents a voucher whose cumulativeAmount exactly matches the channel's already-accepted cumulative amount, the server incorrectly interprets this scenario as an idempotent success rather than a duplicate or invalid request. In a properly secured system, such a condition should trigger a rejection because no new value is being transferred or consumed beyond what has already been accounted for in the ledger state of that specific channel session. However, due to the flawed logic, the function returns the channel unchanged without invoking the maybe_spend/2 callback. This omission is critical because it bypasses the actual deduction of funds or units from the client's balance, effectively allowing the server to serve the protected resource while leaving the spent and unit counters in their previous state.
This flaw becomes particularly dangerous when combined with the authentication and challenge-response mechanism employed by the system. The server issues a fresh cryptographic challenge for every individual request, which typically prevents simple replay attacks where an old signed message is reused against a different context. However, because the credential verification logic stores keys based on both the challenge ID and the payload, it inadvertently allows the same signed voucher to be re-presented under each new, distinct challenge. Consequently, an attacker can repeatedly submit the identical signed voucher across multiple requests. Each submission passes validation as if it were a fresh transaction due to the unique challenge context, yet fails to trigger any state change regarding resource consumption because of the cumulative amount check failure. This results in one paid voucher yielding an unbounded number of free resources, effectively draining server-side value without corresponding client-side debit.
The operational impact of this vulnerability is severe for both service providers and channel operators. Clients holding open payment channels can exploit this logic error to obtain unlimited access to paid services or digital assets without being charged. This not only leads to direct financial loss through the provision of uncompensated resources but also undermines trust in the integrity of the MPP infrastructure. Since the vulnerability is reachable from any method built on Mpp.Session.Method, it affects all supported transport layers including Plug, MCP, JSON-RPC, and WebSocket interfaces. This broad accessibility means that an attacker does not need to target a specific endpoint or protocol variant; they can leverage whichever interface provides access to the session actions to execute the exploit repeatedly until limits are hit or detection occurs.
From a classification perspective, this vulnerability aligns with CWE-20 Improper Input Validation and CWE-345 Insufficient Verification of Data Authenticity. The failure lies in not properly validating that the presented voucher represents a new, distinct transaction rather than a repetition of an already settled one within the context of cumulative accounting. In terms of attack vectors, this behavior is consistent with ATT&CK technique T1078 Valid Accounts, as it requires a legitimate client holding an open channel to abuse their authenticated session privileges for unauthorized resource acquisition. It also touches upon aspects of T1496 Resource Hijacking where the attacker consumes resources that are not theirs or have already been paid for in full context.
Mitigation strategies must focus on correcting the logic within the accept_voucher function to ensure strict idempotency checks based on transaction uniqueness rather than just cumulative amount equality. The system should verify that a voucher has not previously been processed by maintaining a persistent record of consumed vouchers or their unique identifiers, independent of the ephemeral challenge IDs used for authentication. Additionally, implementing stricter bounds checking on the relationship between the presented cumulativeAmount and the current channel state is essential to prevent edge cases where zero-value increments are accepted as valid transactions. Upgrading to version 0.16.2 or later resolves this issue by addressing these validation gaps in the MPP session handling logic. Until an upgrade can be performed, operators should implement strict rate limiting on voucher submissions and monitor for anomalous patterns of repeated identical vouchers being presented under different challenge contexts as a temporary defensive measure.