{
  "affected": [
    {
      "database_specific": {
        "source": "https://cna.erlef.org/osv/EEF-CVE-2026-89186.json"
      },
      "package": {
        "ecosystem": "Hex",
        "name": "mpp",
        "purl": "pkg:hex/mpp"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.1.0"
            },
            {
              "fixed": "0.16.2"
            }
          ],
          "type": "SEMVER"
        }
      ],
      "versions": [
        "0.1.0",
        "0.1.1",
        "0.10.0",
        "0.11.0",
        "0.12.0",
        "0.13.0",
        "0.14.0",
        "0.15.0",
        "0.16.0",
        "0.16.1",
        "0.2.0",
        "0.3.0",
        "0.3.1",
        "0.3.2",
        "0.4.0",
        "0.6.0",
        "0.6.1",
        "0.6.2",
        "0.6.3",
        "0.6.4",
        "0.7.0",
        "0.8.0",
        "0.9.0"
      ]
    },
    {
      "database_specific": {
        "source": "https://cna.erlef.org/osv/EEF-CVE-2026-89186.json"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2d4d1d94aae7790ae0623063961adbeef171fa71"
            },
            {
              "fixed": "2fd91a5ecbd0b0ad2a4ac202b79659e8126dbc0b"
            }
          ],
          "repo": "https://github.com/ZenHive/mpp",
          "type": "GIT"
        }
      ],
      "versions": [
        "v0.16.1",
        "v0.16.0",
        "v0.15.0",
        "v0.14.0",
        "v0.13.0",
        "v0.12.0",
        "v0.11.0",
        "v0.10.0",
        "v0.9.0",
        "v0.8.0",
        "v0.7.0",
        "v0.6.4",
        "v0.6.3",
        "v0.6.1",
        "v0.6.0",
        "v0.5.1",
        "v0.4.0",
        "v0.3.0",
        "v0.2.0",
        "v0.1.0"
      ]
    }
  ],
  "aliases": [
    "CVE-2026-89186",
    "GHSA-82qh-vrvm-gqvc"
  ],
  "credits": [
    {
      "name": "E.FU",
      "type": "FINDER"
    },
    {
      "name": "E.FU",
      "type": "REMEDIATION_DEVELOPER"
    },
    {
      "name": "Jonatan Männchen / EEF",
      "type": "COORDINATOR"
    }
  ],
  "database_specific": {
    "capec_ids": [
      "CAPEC-204"
    ],
    "cpe_ids": [
      "cpe:2.3:a:ZenHive:mpp:*:*:*:*:*:*:*:*"
    ],
    "cwe_ids": [
      "CWE-524"
    ]
  },
  "details": "## Summary\n\nUse 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.\n\n`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.\n\nThis issue affects mpp: from 0.1.0 before 0.16.2.\n\n## Impact\n\nAn 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.\n\n## Workarounds\n\nIn 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.\n\n## Configurations\n\nReachable 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.",
  "id": "EEF-CVE-2026-89186",
  "modified": "2026-09-16T08:40:58.908314385Z",
  "published": "2026-09-16T08:24:15.058Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://github.com/ZenHive/mpp/security/advisories/GHSA-82qh-vrvm-gqvc"
    },
    {
      "type": "WEB",
      "url": "https://cna.erlef.org/cves/CVE-2026-89186.html"
    },
    {
      "type": "WEB",
      "url": "https://github.com/ZenHive/mpp/commit/2d4d1d94aae7790ae0623063961adbeef171fa71"
    },
    {
      "type": "FIX",
      "url": "https://github.com/ZenHive/mpp/commit/2fd91a5ecbd0b0ad2a4ac202b79659e8126dbc0b"
    },
    {
      "type": "PACKAGE",
      "url": "https://hex.pm/packages/mpp"
    }
  ],
  "schema_version": "1.9.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "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"
}