TestProxyHandler_RejectsNonHTTPSTarget verifies end-to-end that a compromised sandbox holding a valid PROXY_KEY cannot coerce the sidecar into forwarding real tokens over cleartext HTTP or to an unexpected path. The check must fire before HMAC verification so that the request is rejected even when t
(t *testing.T)
| 279 | // The check must fire before HMAC verification so that the request is |
| 280 | // rejected even when the signature is technically valid. |
| 281 | func TestProxyHandler_RejectsNonHTTPSTarget(t *testing.T) { |
| 282 | key := []byte("test-key") |
| 283 | h := newTestHandler(key) |
| 284 | |
| 285 | cases := []struct { |
| 286 | name string |
| 287 | target string |
| 288 | }{ |
| 289 | {"http downgrade", "http://open.feishu.cn"}, |
| 290 | {"bare hostname", "open.feishu.cn"}, |
| 291 | {"ftp scheme", "ftp://open.feishu.cn"}, |
| 292 | {"target with path", "https://open.feishu.cn/open-apis/evil"}, |
| 293 | {"target with query", "https://open.feishu.cn?steal=1"}, |
| 294 | {"target with userinfo", "https://attacker:pw@open.feishu.cn"}, |
| 295 | } |
| 296 | for _, tc := range cases { |
| 297 | t.Run(tc.name, func(t *testing.T) { |
| 298 | // Sign with a valid key against the malicious target — proves the |
| 299 | // scheme/shape check is not bypassed by signature legitimacy. |
| 300 | req := signedReq(t, key, "GET", tc.target, "/open-apis/im/v1/chats", nil) |
| 301 | w := httptest.NewRecorder() |
| 302 | h.ServeHTTP(w, req) |
| 303 | if w.Code != http.StatusForbidden { |
| 304 | t.Errorf("expected 403 for target %q, got %d (body: %s)", tc.target, w.Code, w.Body.String()) |
| 305 | } |
| 306 | }) |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | // TestProxyHandler_RejectsIdentityReplay locks in C1 end-to-end: a captured |
| 311 | // bot-signed request whose identity header is flipped to user (or vice versa) |
nothing calls this directly
no test coverage detected