mppx is a TypeScript interface for machine payments protocol. Prior to 0.8.2, FeePayerPolicy in src/tempo/internal/fee-payer.ts used decodeFunctionData to validate fee-sponsored calldata but did not reject trailing bytes. A client could append nonzero padding that increased intrinsic calldata gas while gas_limit and max_fee_per_gas remained within policy caps, causing the server fee_payer wallet to pay substantially more than the decoded transaction required. The tested 16 KB header limit bounded the demonstrated padding to about 5,500 bytes and produced approximately five times the normal transaction fee. This issue is fixed in version 0.8.2.
mppx is a TypeScript interface for machine payments protocol. Prior to 0.8.2, FeePayerPolicy in src/tempo/internal/fee-payer.ts used decodeFunctionData to validate fee-sponsored calldata but did not reject trailing bytes. A client could append nonzero padding that increased intrinsic calldata gas while gas_limit and max_fee_per_gas remained within policy caps, causing the server fee_payer wallet to pay substantially more than the decoded transaction required. The tested 16 KB header limit bounded the demonstrated padding to about 5,500 bytes and produced approximately five times the normal transaction fee. This issue is fixed in version 0.8.2.
mppx is a TypeScript interface for machine payments protocol. Prior to 0.8.2, FeePayerPolicy in src/tempo/internal/fee-payer.ts used decodeFunctionData to validate fee-sponsored calldata but did not reject trailing bytes. A client could append nonzero padding that increased intrinsic calldata gas while gas_limit and max_fee_per_gas remained within policy caps, causing the server fee_payer wallet to pay substantially more than the decoded transaction required. The tested 16 KB header limit bounded the demonstrated padding to about 5,500 bytes and produced approximately five times the normal transaction fee. This issue is fixed in version 0.8.2.
### Details
When the server acts as the fee_payer, `mppx` 0.6.27 validates calldata using viem's `decodeFunctionData`, which is lenient about trailing bytes. The `FeePayerPolicy` caps `gas_limit` (≤ 2 M) and `max_fee_per_gas` (≤ 100 Gwei) but does **not** check calldata length.
Tempo uses legacy calldata gas pricing: **16 gas per non-zero byte**. Appending `N` bytes of `0x01` padding inflates actual gas used by `N × 16` while keeping `gas_limit` and `max_fee_per_gas` within policy caps. The server cosigns and broadcasts the padded transaction, draining its fee-payer wallet.
**Vulnerable code path:** `FeePayerPolicy` in `fee-payer.ts` (mppx 0.6.27) enforces `maxGas = 2_000_000` and `maxFeePerGas = 100 Gwei` but has no `calldata.length` bound. The policy check passes because the inflated gas comes from intrinsic calldata cost, not the declared `gas_limit`.
**Note:** In the experiment, a 16 KB `max_header_length` is enforced, which caps the maximum effective padding at roughly 5,500 bytes. The default padding in this PoC (5,500 bytes) is within that limit.
### PoC
The PoC is provided below. It is configured to reproduce the attack on Tempo Moderate testnet within a Docker environment. Download the PoC and run:
```bash
unzip mppx_typescript_PoC.zip
cd mppx_typescript
docker build -t mppx-padding .
docker run --rm mppx-padding
```
There are more details in `mppx_typescript/README.md`
### Impact
A malicious client can force the server to pay ~**5x** the normal transaction fee. This dramatically increases operational costs and completely destroys the profit margin on low-cost items.
Please provide a way to share the PoC in .zip format to you. Thank you!
EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.
Original publisher date fields
datePublished: Sep 22, 2026, 7:07:02 PM
dateUpdated: Sep 23, 2026, 2:36:37 PM
No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.
NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.
Source analysis status: Awaiting Analysis
Weakness classifications: CWE-20
Original publisher date fields
published: 2026-09-22T20:17:04.763
lastModified: 2026-09-23T18:12:04.247
No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.