{"id":"CVE-2026-41644","aliases":["GHSA-29v9-frvh-c426","GO-2026-4966"],"url":"https://o3.security/vulnerability/CVE-2026-41644","summary":"monetr is vulnerable to server-side request forgery in Lunch Flow link creation and refresh","details":"### Impact\n\nA server-side request forgery (SSRF) vulnerability in monetr's Lunch Flow integration allowed any authenticated user on\na self-hosted instance to cause the monetr server to issue HTTP GET requests to arbitrary URLs supplied by the caller,\nwith the response body from non-200 upstream responses reflected back in the API error message.\n\nThe URL validator on `POST /api/lunch_flow/link` only checked the URL scheme and rejected query parameters; it did not\nfilter loopback, RFC1918, link-local, or cloud-provider metadata addresses. The outbound HTTP client read the response\nbody via an unbounded `io.ReadAll`, and the controller intentionally surfaced the resulting error (which contained the\nupstream body) as the JSON `error` field of the API response.\n\n**Who is affected:** self-hosted monetr deployments running the default configuration. Out of the box,\n`LunchFlow.Enabled=true`, `AllowSignUp=true`, and billing is not enforced, so any user who can register on the instance\ncan reach the vulnerable endpoint. Deployments running in a cloud environment where instance metadata is reachable from\nthe pod (e.g. AWS EC2 without IMDSv2 enforced) expand the impact to include potential exposure of instance metadata\nthrough the reflected error body.\n\n**Who is NOT affected:** the hosted `my.monetr.app` service, which runs with `LunchFlow.Enabled=false`. Self-hosted\noperators who had already disabled public sign-up (`MONETR_ALLOW_SIGN_UP=false`) substantially reduce their exposure\nsince only operator-trusted users can reach the endpoint.\n\nA secondary denial-of-service vector also existed: because the outbound response body was read with no size cap, an\nattacker-influenced upstream could return a multi-GB body that monetr would fully buffer into memory.\n\n### Patches\n\nFixed in monetr `v1.12.5`. Users should upgrade to this release or later.\n\nThe fix introduces a new config field `LunchFlow.AllowedApiUrls` (a list of permitted Lunch Flow API URLs) with a\ndefault of `[\"https://lunchflow.app/api/v1\"]`. URLs outside the allowlist are rejected both at link-creation time and at\nclient-construction time, with a server-side warning log on rejection. Response body reads are capped at 10 MiB for both\nsuccess and error paths. The UI renders the API URL field as a disabled pre-filled input when a single URL is allowed,\nor a dropdown when multiple are allowed, so operators who need to use a staging or self-hosted Lunch Flow API opt in\nexplicitly via config.\n\n**Upgrade note for self-hosters with a custom Lunch Flow URL:** if your existing `LunchFlowLink` records point at a URL\nother than `https://lunchflow.app/api/v1`, set your `lunchFlow.allowedApiUrls` in your yaml config to include your\ncustom URL before upgrading. Otherwise existing links will fail on next refresh or sync with a `\"Rejected Lunch Flow API\nURL that is not in the configured allowlist\"` warning in the server log.\n\n### Workarounds\n\nFor operators who cannot upgrade immediately, any of the following materially reduces or eliminates exposure:\n\n- **Disable public sign-up:** set `MONETR_ALLOW_SIGN_UP=false` so only operator-trusted users can reach the vulnerable\nendpoint. Recommended in general for internet-exposed self-hosted deployments.\n- **Disable Lunch Flow entirely:** set `lunchFlow.enabled: false` in your config file. The endpoints will return 404 for\nall callers.\n- **Network-level egress restriction:** restrict outbound HTTP egress from the monetr pod/container to only\n`lunchflow.app` (or whichever legitimate Lunch Flow hosts you use). Blocks the SSRF primitive regardless of\napplication-layer validation.\n- **On AWS EC2 specifically:** enforce IMDSv2 on the instance. This eliminates the cloud-metadata exfil path even if the\nSSRF primitive remains reachable.","published":"2026-05-07T11:56:37.721Z","modified":"2026-08-12T03:51:44.127445089Z","cvss":null,"epss":{"score":0.00331,"percentile":0.25851,"asOf":"2026-08-13"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Go","name":"github.com/monetr/monetr","fixedVersion":"1.12.5"}],"fix":{"url":"https://github.com/monetr/monetr/commit/c260caa3c573a4a396ec2d264c7641a5d958385b","label":"monetr/monetr@c260caa"},"references":[{"type":"WEB","url":"https://github.com/monetr/monetr/releases/tag/v1.12.5"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/41xxx/CVE-2026-41644.json"},{"type":"ADVISORY","url":"https://github.com/monetr/monetr/security/advisories/GHSA-29v9-frvh-c426"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-41644"},{"type":"FIX","url":"https://github.com/monetr/monetr/commit/c260caa3c573a4a396ec2d264c7641a5d958385b"},{"type":"FIX","url":"https://github.com/monetr/monetr/pull/3122"},{"type":"PACKAGE","url":"https://github.com/monetr/monetr"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:44.127445089Z"}}