CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-VJ8P-HP9X-GH47

GHSA-vj8p-hp9x-gh47: Zero-Cost Fee-Payer Wallet Gas Draining in mpp Elixir Library

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 26, 2026·6 min read·13 visits

Executive Summary (TL;DR)

An unauthenticated attacker can submit transaction payloads with insufficient gas limits to the `mpp` fee-payer endpoint. This forces the sponsor's wallet to pay for failed execution costs while the attacker incurs zero financial cost, draining the host's wallet and causing a denial of service.

A high-severity vulnerability exists in the Elixir library `mpp` (Multi-Party Payments) prior to version `0.6.0`. When acting as a sponsored transaction fee payer, the server co-signs and broadcasts user-provided transactions without verifying if the user-specified gas limit is sufficient. An attacker can submit transactions designed to run out of gas and revert. The transaction reversion ensures the attacker pays zero fees, while the sponsor's fee-payer wallet is fully billed for the wasted gas, resulting in a low-cost, high-impact Denial of Service (DoS) vector.

Vulnerability Overview

The mpp Elixir library (ZenHive/mpp) provides multi-party payments and transaction sponsorship services. When configured to act as a "fee payer" or transaction sponsor, the server takes a client's signed transaction envelope (typically type 0x76 on Tempo-enabled chains), co-signs it as the paying party, and broadcasts it to the EVM network. This architecture is designed to hide transaction fee complexity from end-users by paying native blockchain execution gas on their behalf.

The attack surface exists at the transaction submission endpoint. Because any unauthenticated client can request sponsorship, the server must strictly validate all input parameters in the transaction envelope. Prior to version 0.6.0, the library failed to validate whether the gas_limit specified by the client was sufficient for successful contract execution.

This flaw is classified under CWE-20 (Improper Input Validation). By supplying a gas_limit that is mathematically lower than the actual execution requirements, an attacker can trigger an on-chain execution revert. Because the transaction reverts, the attacker incurs no financial cost, while the sponsor's fee-paying wallet is charged for the wasted gas.

Root Cause Analysis

To understand the vulnerability, it is necessary to examine how mpp managed transaction confirmation paths. The system offered two dispatch routes: a synchronous path (wait_for_confirmation = true) and an optimistic asynchronous path (wait_for_confirmation = false). Both paths introduced critical validation gaps.

On the synchronous confirmation path, the library omitted simulation completely. It invoked the rpc_broadcast_sync function immediately after co-signing the transaction. This logic left the server entirely blind to the contract's actual execution parameters and runtime state, broadcasting raw hex data without pre-verification.

On the optimistic path, the library attempted validation via a private function named simulate_payment_call/3. However, this function was fundamentally flawed. It executed a standard eth_call targeting only the inner raw parameters (to and input calldata). It completely omitted the client-supplied gas_limit from the JSON-RPC payload, meaning the simulation node assumed default or infinite gas. Consequently, transactions with insufficient gas limits simulated as successful but failed catastrophically when executed on-chain.

Code Analysis

The code-level mistake is located in lib/mpp/methods/tempo.ex. In the vulnerable implementation, the synchronous path executed a direct broadcast while the optimistic path used a flawed helper function:

# Vulnerable synchronous path (pre-0.6.0)
defp broadcast_and_verify(%Transaction{raw: raw_hex}, rpc_url, config, charge, memo, true, _payment_call) do
  rpc_opts = rpc_options(config)
  # Missing simulation check before broadcasting
  with {:ok, tx_hash, receipt} <- rpc_broadcast_sync(raw_hex, rpc_url, rpc_opts),
       :ok <- check_receipt_status(receipt),
       {:ok, _transfer} <- find_matching_transfer(receipt, charge, memo) do
    {:ok, tx_hash}
  end
end

The corresponding validation helper on the optimistic path was also ineffective because it simulated a bare contract call without copying the outer transaction metadata or specifying gas parameters:

# Vulnerable optimistic path simulation (pre-0.6.0)
defp simulate_payment_call(%{to: to, input: input}, rpc_url, config) do
  to_hex = "0x" <> Base.encode16(to, case: :lower)
  data_hex = "0x" <> Base.encode16(input, case: :lower)
  body = Jason.encode!(%{
    "jsonrpc" => "2.0",
    "method" => "eth_call",
    # Vulnerability: "gas" parameters are omitted completely
    "params" => [%{"to" => to_hex, "data" => data_hex}, "latest"],
    "id" => 1
  })
  # ... requests sent to JSON-RPC backend ...
end

To resolve this issue, the patch introduced in version 0.6.0 replaced these sections with a pre-broadcast transaction simulation using the standard eth_simulateV1 JSON-RPC method. This method processes the entire co-signed transaction envelope, ensuring that recovered senders, signature structures, and user-defined gas parameters are fully evaluated before any gas is committed on-chain.

Exploitation Methodology

An attacker can exploit this vulnerability with zero financial cost. To initiate the attack, the adversary must first identify a transaction that the target server is willing to sponsor. For instance, a basic contract call such as transferWithMemo on the Tempo Moderato network might require exactly 51,299 gas units to execute successfully.

The attacker crafts a custom 0x76 transaction envelope. Instead of setting the gas limit to 51,299, the attacker specifies a gas_limit of exactly 51,298 (one gas unit below the minimum runtime requirement). When this payload is sent to the vulnerable mpp endpoint, the server co-signs and broadcasts it.

During EVM block execution, the EVM processes the transaction up to its limit of 51,298 gas units. Because it lacks the final gas unit to write to state or complete execution, the EVM halts execution and throws an Out-of-Gas (OOG) error. All state changes associated with the user's action are reverted, meaning the attacker pays nothing. However, because the transaction was validly signed and broadcasted, the network still charges the sponsor's fee-payer wallet for the entire 51,298 gas burned prior to the failure.

Architectural Nuances & Bypass Vectors

Although the patch in version 0.6.0 is robust, security researchers must account for several architectural nuances when auditing this implementation.

To ensure compatibility with older EVM RPC endpoints that do not implement standard Account Abstraction simulation protocols, the developers added a graceful degradation path. If the RPC node returns a JSON-RPC error code of -32601 (method not found) for eth_simulateV1, the server records an info log and continues to broadcast the transaction anyway:

{:ok, :unsupported} ->
  Logger.info("MPP.Methods.Tempo: node does not implement eth_simulateV1; skipping pre-broadcast simulation")
  :ok

This design decision introduces a fallback vulnerability. If an attacker can force the server's RPC queries to route to an older node, or if an administrator unknowingly deploys the package against a legacy node, the gas-draining protection is completely disabled.

Additionally, simulation is bound to the Time-of-Check to Time-of-Use (TOCTOU) problem. A transaction may simulate successfully against the state of block N, but if another transaction modifies contract state in the same block before the sponsored transaction is mined, the transaction may still revert on-chain. While this is an inherent limitation of EVM environments, it represents a potential vector for targeted exploit scenarios.

Remediation

Remediation of this vulnerability requires upgrading the mpp package to version 0.6.0 or higher. This upgrade forces the dependent library onchain_tempo to version 0.7.0 which contains the necessary logic to structure eth_simulateV1 calls.

To apply the update, modify your Elixir configuration in mix.exs:

def deps do
  [
    {:mpp, "~> 0.6.0"}
  ]
end

Once updated, execute mix deps.update mpp and ensure your lockfile registers the correct version. Developers should also verify that their upstream JSON-RPC node provider fully supports the eth_simulateV1 method. If the node logs the skipping pre-broadcast simulation warning, the service remains exposed to wallet exhaustion.

Official Patches

ZenHiveFix commit implementing eth_simulateV1 transaction validation.

Fix Analysis (1)

Technical Appendix

CVSS Score
8.8/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N

Affected Systems

mpp Elixir library deployments configured as transaction fee-payer / sponsorsEVM-compatible Multi-Party Payment systems running on Tempo or related Account Abstraction protocols

Affected Versions Detail

Product
Affected Versions
Fixed Version
mpp
ZenHive
>= 0.2.0, < 0.6.00.6.0
AttributeDetail
CWE IDCWE-20
Attack VectorNetwork
CVSS Score8.8
ImpactDenial of Service (DoS) via Wallet Exhaustion
Exploit StatusProof-of-Concept (PoC) Available
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499.004Endpoint Denial of Service: Application Exhaustion Flood
Impact
CWE-20
Improper Input Validation

The application fails to validate the user-supplied gas_limit input in the transaction envelope against a minimum required threshold or simulation baseline before committing the server's wallet to pay for it.

Known Exploits & Detection

GitHub Security Advisory PageExploit blueprint detailing setup instructions for single-transaction and multi-transaction DoS scenarios using Docker.

References & Sources

  • [1]GHSA-vj8p-hp9x-gh47 Advisory on GitHub
  • [2]ZenHive/mpp Advisory Details
  • [3]Fix Commit in GitHub Repository
  • [4]mpp v0.6.0 Release Tag

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•15 minutes ago•CVE-2026-108262
6.5

CVE-2026-108262: Arbitrary Host File Overwrite via Tar Symlink Traversal in DDEV

CVE-2026-108262 (GHSA-9hq4-hm3j-jmph) is a path traversal and arbitrary file overwrite vulnerability in the tar archive extraction routine of DDEV versions 1.25.2 and 1.25.3. Resulting from an incomplete fix for CVE-2026-32885, the Untar function in pkg/archive/archive.go validates absolute symbolic link targets by rebasing them against the extraction destination directory, but subsequently creates the symbolic link on disk using the raw, unvalidated absolute path. When subsequent entries in the archive write through the planted symbolic link, the host operating system resolves the link directly to the host filesystem, allowing an attacker to overwrite arbitrary files with the privileges of the user executing DDEV.

Amit Schendel
Amit Schendel
0 views•10 min read
•about 1 hour ago•CVE-2026-119298
4.2

CVE-2026-119298: Overwrite Confirmation Bypass in schollz/croc via Unvalidated Text Artifact Prefix

CVE-2026-119298 (GHSA-x89h-7h96-v88f) is a file overwrite confirmation bypass vulnerability in schollz/croc prior to version 11.5.2. The receive-side file validation logic in src/croc/croc.go improperly exempted any incoming file whose basename began with the prefix 'croc-stdin-' from interactive overwrite prompts and automatic collision renaming, failing to verify if the transfer session was actually an internal text transfer. An unauthenticated remote peer participating in a transfer session can exploit this flaw to silently overwrite, truncate, or replace matching pre-existing files in the receiver's working directory.

Amit Schendel
Amit Schendel
3 views•9 min read
•about 2 hours ago•CVE-2026-88968
7.7

CVE-2026-88968: TOCTOU Race Condition in Claude Code Edit Tool Allows Arbitrary File Overwrite

Claude Code prior to version 2.1.251 contains a Time-of-Check to Time-of-Use (TOCTOU) race condition in its internal file manipulation tools (Edit, Write, Read). Because path validation was performed using string-based pathname and symbolic link resolution without binding to the underlying directory inodes or open file descriptors, a process running concurrently inside the macOS Bash sandbox can atomically replace an in-workspace directory with a symbolic link after validation passes. This causes the unsandboxed main process to follow the symlink and overwrite user-writable files outside the permitted workspace boundary.

Alon Barad
Alon Barad
4 views•9 min read
•about 3 hours ago•CVE-2026-88982
5.4

CVE-2026-88982: Cross-Tenant Execution Cache Poisoning and Output Substitution in Kubeflow Pipelines

CVE-2026-88982 (GHSA-2xwh-426q-42c5) is an authorization bypass and data integrity vulnerability affecting Kubeflow Pipelines versions prior to 2.18.0. The flaw resides in the legacy V1 and raw-Argo execution caching mutating admission webhook and the associated cache-server storage backend. In multi-tenant deployments where namespaces share a centralized cache service, execution cache keys were derived solely from container specification fields without incorporating the workload's Kubernetes namespace. Additionally, the cache watcher trusted mutable pod annotations when persisting execution outputs. Consequently, an authenticated user with workload submission privileges in one tenant namespace can poison cached step outputs consumed by other tenants or read cached outputs generated by workloads in separate namespaces.

Amit Schendel
Amit Schendel
8 views•12 min read
•about 4 hours ago•CVE-2026-88983
5.0

CVE-2026-88983: Authenticated Server-Side Request Forgery in Kubeflow Pipelines API Server

CVE-2026-88983 is an authenticated Server-Side Request Forgery (SSRF) vulnerability affecting the Kubeflow Pipelines API server in versions prior to 2.17.0. When an authenticated user creates a pipeline or pipeline version using a remote specification URI, the backend server retrieves the document via Go's default HTTP client without validating the target scheme, hostname, port, or IP address. Because the API server reflects remote connection errors and HTTP status codes in its response, an attacker with pipeline creation permissions can exploit the server as a status-code and port-scanning oracle against Kubernetes cluster-internal services, private networks, and cloud metadata endpoints.

Amit Schendel
Amit Schendel
4 views•11 min read
•about 5 hours ago•CVE-2026-88985
6.5

CVE-2026-88985: SQL Injection via Pagination Token Deserialization and Metric Sorting in Kubeflow Pipelines API Server

CVE-2026-88985 is a SQL injection vulnerability (CWE-89) in the Kubeflow Pipelines (KFP) API server prior to version 2.17.0. The flaw stems from the untrusted deserialization of base64-encoded JSON pagination tokens (page_token) and the direct concatenation of metric names during run list sorting. Authenticated users with permissions to invoke REST or gRPC list endpoints can inject arbitrary SQL syntax into structural query identifiers and JOIN predicates, enabling unauthorized cross-tenant read access to all database records accessible by the API server.

Alon Barad
Alon Barad
4 views•10 min read