CVE-2026-87119 Overview
CVE-2026-87119 is an authentication bypass by capture-replay flaw in ZenHive mpp, an Elixir library implementing the Merchant Payment Protocol. The vulnerability affects Tempo subscription activation. An attacker who captures a valid KeyAuthorization credential can replay it against fresh subscription challenges to charge the payer's wallet repeatedly. The signed authorization is not bound to the challenge that prompted it, so the server accepts the same signature under any new challenge sharing the same subscription terms.
The issue affects mpp from version 0.14.0 before 0.16.2 and is tracked as [CWE-294: Authentication Bypass by Capture-replay].
Critical Impact
Each successful replay triggers a new first-period settlement against the payer's wallet and re-authorizes the server key, causing repeatable, unauthorized financial charges bounded only by the subscription expiry.
Affected Products
- ZenHive mpp version 0.14.0
- ZenHive mpp versions up to (but not including) 0.16.2
- Applications embedding the vulnerable MPP.Methods.Tempo.Subscription module
Discovery Timeline
- 2026-09-22 - CVE-2026-87119 published to NVD
- 2026-09-22 - Last updated in NVD database
Technical Details for CVE-2026-87119
Vulnerability Analysis
The vulnerability resides in how mpp verifies Tempo subscription key authorizations. The payer signs a KeyAuthorization over the chain id, key type, key id, expiry, limits, and scopes. No field in the signed payload ties the authorization to the specific challenge that prompted it. The signature is therefore reusable across any challenge that shares the same subscription terms.
Because the pinned access key is a static per-endpoint server key, one signed authorization verifies against every challenge the server issues for that subscription. An attacker that captures the credential once can present it repeatedly against freshly issued challenges to activate the subscription again.
Root Cause
MPP.Methods.Tempo.KeyAuthorization.verify/3 in lib/mpp/methods/tempo/key_authorization.ex pins the signed fields against the subscription request but omits any challenge-specific binding. MPP.Methods.Tempo.Subscription.activate/4 deduplicates activations by challenge id. Presenting a captured credential under a new challenge produces a different dedup key, so claim_activation succeeds and the subscription transaction is built and broadcast a second time.
Attack Vector
Exploitation is network-based and requires the attacker to first capture a valid KeyAuthorization message. Once captured, the attacker requests a new subscription challenge from the server using the same subscription terms, submits the replayed authorization, and triggers a new activation. Each replay charges the payer's wallet a fresh first-period settlement and re-installs the server key, bounded only by subscription expiry and chain semantics for re-installing an existing key.
# Patch: bind KeyAuthorization to the challenge id
{:ok, params} <-
KeyAuthorization.wallet_params(subscription,
access_key: access_key,
- key_type: key_type
+ key_type: key_type,
+ challenge_id: challenge.id
),
{:ok, authorization} <- authorize_access_key(wallet_rpc_url, params, config[:req_options]),
:ok <-
KeyAuthorization.verify(authorization, subscription,
chain_id: chain_id,
access_key: access_key,
key_type: key_type,
- challenge_expires: challenge.expires
+ challenge_expires: challenge.expires,
+ challenge_id: challenge.id
) do
Source: GitHub Commit 4b6eaec
Detect Identity Attacks the Moment Authentication Fails
Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.
Stop Identity AttacksDetection Methods for CVE-2026-87119
Indicators of Compromise
- Multiple successful subscription activations for the same payer and subscription terms within a short window, each tied to a different challenge id.
- Repeat first-period settlement transactions broadcast to the chain against the same payer wallet.
- Repeat key re-authorization events for the same static per-endpoint server key.
Detection Strategies
- Correlate claim_activation success events against unique payer/subscription pairs and alert when the same pair activates more than once per subscription period.
- Inspect application logs for MPP.Methods.Tempo.Subscription.activate/4 invocations that reuse an authorization signature across distinct challenge ids.
- Monitor on-chain events for duplicate first-period settlements originating from the same wallet with the same server key.
Monitoring Recommendations
- Ingest mpp server logs and wallet transaction telemetry into a centralized data lake for cross-correlation of activation and settlement events.
- Baseline expected subscription activation frequency per payer and alert on deviations that suggest replay attempts.
- Track the mpp dependency version across services and flag any deployment running a release earlier than 0.16.2.
How to Mitigate CVE-2026-87119
Immediate Actions Required
- Upgrade mpp to version 0.16.2 or later across all deployments that use Tempo subscriptions.
- Rotate any static per-endpoint server keys that were in use during the window of exposure.
- Audit recent subscription activations and on-chain settlements for repeated first-period charges against the same payer.
Patch Information
The fix is delivered in mpp0.16.2. Commit 4b6eaec binds the Tempo KeyAuthorization to the originating challenge_id in both KeyAuthorization.wallet_params/2 and KeyAuthorization.verify/3, so a captured authorization no longer verifies against a different challenge. Commit db464df adds a dedicated MPP.Subscription.ETSStore and hardens challenge kind validation. See the GitHub Security Advisory GHSA-p9fv-9w58-95x2 and the CNA advisory for CVE-2026-87119.
Workarounds
- If patching is delayed, tighten subscription expiry windows to minimize the replay window for captured credentials.
- Enforce short-lived, single-use challenges at the application layer and reject any activation whose challenge id has already been consumed by the same payer.
- Restrict access to the subscription activation endpoint via mutual TLS or network allow-lists to reduce credential capture opportunities.
# Pin the fixed version in mix.exs
# {:mpp, "~> 0.16.2"}
mix deps.update mpp
mix deps.get
mix compile
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

