VDB
Sign up

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 mpp

Details

## 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

Hex/mpp
Introduced in: 0.1.0Fixed in: 0.16.2
Fixmix deps.update mpp

References