{"id":"GHSA-29v9-frvh-c426","summary":"monetr: 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.","aliases":["CVE-2026-41644","GO-2026-4966"],"modified":"2026-05-20T19:41:17.425232344Z","published":"2026-04-22T19:57:54Z","database_specific":{"github_reviewed_at":"2026-04-22T19:57:54Z","nvd_published_at":"2026-05-07T12:16:17Z","cwe_ids":["CWE-209","CWE-770","CWE-918"],"severity":"HIGH","github_reviewed":true},"references":[{"type":"WEB","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":"WEB","url":"https://github.com/monetr/monetr/pull/3122"},{"type":"WEB","url":"https://github.com/monetr/monetr/commit/c260caa3c573a4a396ec2d264c7641a5d958385b"},{"type":"PACKAGE","url":"https://github.com/monetr/monetr"},{"type":"WEB","url":"https://github.com/monetr/monetr/releases/tag/v1.12.5"}],"affected":[{"package":{"name":"github.com/monetr/monetr","ecosystem":"Go","purl":"pkg:golang/github.com/monetr/monetr"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.12.5"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-29v9-frvh-c426/GHSA-29v9-frvh-c426.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:L/SC:H/SI:N/SA:N"}]}