CVE-2026-59694 Overview
CVE-2026-59694 is an improper input validation vulnerability [CWE-1284] in the ZenHive mpp Elixir library. When mpp runs as a fee payer with fee_payer: true, the MPP.Tempo.Transaction.cosign_fee_payer/3 function re-signs client-supplied base fields of the 0x76 AASigned envelope without validating the EIP-2930 access list length. An unauthenticated remote client can attach a padded access list to a valid transferWithMemo call. The server co-signs and broadcasts the transaction, forcing the sponsor wallet to pay intrinsic gas for every fabricated entry. The flaw affects mpp versions 0.2.0 through versions before 0.6.0.
Critical Impact
At the default of 137 access-list entries and 100 Gwei max_fee_per_gas, per-payment gas cost rises from ~51,287 to ~380,087 gas — a 7.4x multiplier that drains the fee-payer wallet under sustained abuse.
Affected Products
- ZenHive mpp Elixir library >= 0.2.0
- ZenHive mpp Elixir library < 0.6.0
- Applications configured with fee_payer: true using the Tempo transaction cosigner
Discovery Timeline
- 2026-07-17 - CVE-2026-59694 published to NVD
- 2026-07-17 - Last updated in NVD database
Technical Details for CVE-2026-59694
Vulnerability Analysis
The mpp library provides sponsored transaction support on the Tempo chain. When configured as a fee payer, MPP.Tempo.Transaction.cosign_fee_payer/3 accepts a client-supplied 0x76 AASigned envelope, appends the sponsor signature, and broadcasts it. The cosigner does not inspect the EIP-2930 access list carried in the envelope. Every access-list address adds ~2,400 intrinsic gas and every storage key adds ~1,900 intrinsic gas, charged before opcode execution regardless of runtime access. A malicious client can therefore convert access-list entries directly into sponsor cost with no on-chain effect.
Root Cause
The cosigning path treats the base transaction fields as opaque and preserves them verbatim during re-signing. No policy bounds max_gas, max_fee_per_gas, max_priority_fee_per_gas, max_total_fee, or access-list size before the sponsor signature is applied. The maintainer's default request size fits 137 access-list entries within Bandit's 10,000-byte per-header-field limit, providing the ceiling the attacker exploits.
Attack Vector
An unauthenticated remote attacker submits a well-formed transferWithMemo payload with a padded EIP-2930 access list. The sponsor co-signs and broadcasts. The transfer succeeds on-chain, but the fee-payer wallet is billed a 7.4x gas multiplier per payment. Repeated calls erode the sponsor's operating margin and eventually drain the wallet.
secp256k1 private key for the fee payer account
* `"fee_token"` — (required when `fee_payer: true`) hex address of a USD-denominated
TIP-20 token to use for fee payment (e.g., pathUSD)
+ * `"fee_payer_policy"` — (optional, `fee_payer: true` only) map of sponsor
+ ceilings overriding the per-chain defaults: `"max_gas"`,
+ `"max_fee_per_gas"`, `"max_priority_fee_per_gas"`, `"max_total_fee"` (wei),
+ and `"max_validity_window_seconds"` (seconds). Bounds the client-supplied
+ gas fields and validity window before the server co-signs so a malicious
+ client cannot drain the fee-payer wallet via inflated gas price, total fee
+ budget, or a padded access list, nor hold a co-signed sponsorship
+ broadcastable far into the future. See `MPP.Methods.Tempo.FeePayerPolicy`.
* `"memo"` — (optional) bytes32 hex memo for `transferWithMemo`
Source: ZenHive/mpp commit 5d6338e — this patch introduces the fee_payer_policy map that bounds gas and access-list inputs before co-signing.
Detection Methods for CVE-2026-59694
Indicators of Compromise
- Broadcast transactions signed by the sponsor wallet where gasUsed far exceeds the ~51,287 baseline for transferWithMemo.
- EIP-2930 access lists containing dozens to hundreds of entries that are never touched during execution.
- Sponsored transactions whose serialized envelope approaches Bandit's 10,000-byte per-header-field limit.
Detection Strategies
- Parse the accessList field of every co-signed transaction and alert when entry count exceeds an operational baseline (e.g., 5–10 entries).
- Compare gasUsed against the expected intrinsic + call cost for transferWithMemo; flag any ratio above 1.5x.
- Correlate repeated high-gas sponsorship events to the same client identifier or IP to identify sustained abuse.
Monitoring Recommendations
- Track fee-payer wallet balance velocity and alert on abnormal outflow rates.
- Log the size and entry count of every AASigned envelope accepted by cosign_fee_payer/3.
- Monitor request header sizes served by Bandit for values near the 10,000-byte limit.
How to Mitigate CVE-2026-59694
Immediate Actions Required
- Upgrade the mpp Elixir library to version 0.6.0 or later.
- Configure fee_payer_policy with explicit max_gas, max_fee_per_gas, max_priority_fee_per_gas, and max_total_fee ceilings appropriate to your payment size.
- Rotate the fee-payer key if wallet drainage or anomalous gas spend has been observed.
Patch Information
The fix is delivered in commit 5d6338e2334084c5f2a78cfcca474830733ed7e8 and released in mpp0.6.0. The patch adds MPP.Methods.Tempo.FeePayerPolicy, which bounds the client-supplied gas fields, total fee budget, validity window, and access-list padding before the server co-signs. Details are in GHSA-qpxh-ff8m-c62v and the CNA notification.
Workarounds
- Disable the fee-payer role (fee_payer: false) until the upgrade is applied.
- Front the mpp endpoint with a reverse proxy that rejects requests whose serialized transaction exceeds a strict byte ceiling well below 10,000 bytes.
- Require authenticated clients and rate-limit sponsorship requests per client to reduce sustained abuse.
# Configuration example — apply sponsor ceilings when initializing the fee payer
config :mpp, MPP.Methods.Tempo,
fee_payer: true,
fee_token: "0x...",
fee_payer_policy: %{
"max_gas" => 100_000,
"max_fee_per_gas" => 100_000_000_000,
"max_priority_fee_per_gas" => 2_000_000_000,
"max_total_fee" => 10_000_000_000_000_000,
"max_validity_window_seconds" => 300
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

