EEF-CVE-2026-89186
mpp writes Payment-Receipt and Cache-Control before the wrapped application runs, letting a consumer's own Cache-Control expose paid responses to shared caches
Quick fix
EEF-CVE-2026-89186 — mpp: upgrade to the fixed version with the command below.
mix deps.update mppDetails
## Summary
Use of Cache Containing Sensitive Information in ZenHive mpp allows a shared HTTP cache to store a paid response and serve it to clients that never paid.
`MPP.Plug.verify_credential` in `lib/mpp/plug.ex` sets `payment-receipt` and `cache-control: private` on the connection before the wrapped application runs, and registers no `register_before_send/2` callback. `Plug.Conn.put_resp_header/3` replaces an existing header, so a mounting application that sets its own `cache-control` on the paid resource (for example `public, max-age=3600`) silently overrides the `private` the library relies on, and a CDN or reverse proxy can then store the paid 200 together with its `Payment-Receipt` and serve both to unpaid clients. The library-level guarantee is therefore defeatable by the application it protects. For the same reason a downstream non-2xx response still carried `Payment-Receipt`, issuing a receipt for a response that delivered no resource.
This issue affects mpp: from 0.1.0 before 0.16.2.
## Impact
An unpaid client requesting the same URL through the shared cache receives the cached paid response, including the `Payment-Receipt` header issued to the paying client. Operators lose the revenue for every cache hit, and the receipt identifying a paid transaction is disclosed to third parties.
## Workarounds
In the application mounted behind `MPP.Plug`, stop setting `Cache-Control` on paid routes so the library's `private` survives to the response, or set a directive that is itself safe for a shared cache (`private`, or `no-store`). Where the application must set its own caching policy, configure the CDN or reverse proxy not to cache responses carrying a `Payment-Receipt` header.
## Configurations
Reachable only where the application mounted behind `MPP.Plug` sets its own `Cache-Control` on the paid resource, overriding the `private` the library wrote, and a shared HTTP cache (CDN or reverse proxy) sits in front of that route. An application that sets no `Cache-Control` of its own keeps the library's `private` and is not affected.
Are you affected?
Enter the version of the package you're using.
Affected packages
References
- https://github.com/ZenHive/mpp/security/advisories/GHSA-82qh-vrvm-gqvc[ADVISORY]
- https://cna.erlef.org/cves/CVE-2026-89186.html[WEB]
- https://github.com/ZenHive/mpp/commit/2d4d1d94aae7790ae0623063961adbeef171fa71[WEB]
- https://github.com/ZenHive/mpp/commit/2fd91a5ecbd0b0ad2a4ac202b79659e8126dbc0b[FIX]
- https://hex.pm/packages/mpp[PACKAGE]