CVE-2026-67581 is a high severity (CVSS 7.5) authentication bypass in ZenHive mpp, an Elixir machine payments library. Versions 0.3.0 up to 0.6.3 accept one settled on-chain transfer as proof for unlimited later charges. Upgrade to mpp 0.6.3 and configure a dedup store.
What's affected
The record says mpp from 0.3.0 before 0.6.3 is affected. The GitHub advisory (GHSA-vp5h-xh25-44wf) says versions up to and including 0.6.2 are affected, and 0.6.3 is patched. The two agree on the fix.
The affected function is the EVM payment method verification. The advisory says it matched a transfer only on token, recipient and amount (or recipient and value for native transfers). It bound the proof neither to the challenge being checked nor to earlier use.
The impact grows with static pricing. On a route with a fixed price, one real historical transfer that matches the charge can pay for many later requests. The record notes that the attacker can read such transfers from a public block explorer, so the attacker does not even need to pay once.
How to check if you're exposed
mix deps | grep mpp
grep mpp mix.lock
The lock file records the exact resolved version, so check it rather than the version range in mix.exs.
Then look at how your routes charge. Any route with a static price that uses the EVM method is in scope. Check whether you configured a dedup store, and with what lifetime:
grep -rn "MPP.Plug\|Methods.EVM\|dedup" lib/ config/
Compare revenue and request logs for routes that served many paid responses against few on-chain payments.
A quicker route for a whole project is the free in-browser dependency scan at Gold. Paste a manifest or lockfile and it matches each dependency against known CVEs, including ones pulled in indirectly.
What to do now
- Upgrade mpp to 0.6.3 or later.
- After upgrading, configure a dedup store with a lifetime at least as long as the challenge expiry, as the advisory says.
- Until you can upgrade, use per-challenge or single-use pricing, a short challenge expiry, or the Tempo method for on-chain payments.
- Reconcile paid responses against on-chain transfers for the period you ran an affected version.
- Record transaction hashes you have accepted, so a hash cannot satisfy a second charge.
Reachability analysis helps with ordering the work. Knowing whether your code actually calls the affected path tells you which services to patch first.
Why it matters
The class is CWE-294, authentication bypass by capture-replay. A payment proof should be usable once. Here the check confirmed that a matching transfer existed, but not that it was new or that it was meant for this request. The generic dedup store keyed on challenge identifiers, and those are regenerated for every response, so reuse of the same transaction hash was never caught.
This is a plain business logic flaw, not a memory bug, and a scanner will not find it by pattern. The control that closes it is state: remember what you have already accepted. The record does not mark this CVE as known exploited.
Quick check
Does the fix need configuration?
Yes. After upgrading, the advisory says to configure a dedup store with a lifetime at least as long as the challenge expiry.
Who can abuse this?
The record says an unauthenticated remote client, using a transfer that already settled on-chain.
Sources
- https://github.com/ZenHive/mpp/security/advisories/GHSA-vp5h-xh25-44wf
- Record: NVD entry for CVE-2026-67581 (score 7.5, HIGH)
Last reviewed: 18 October 2026.