{"record":{"id":"3090a7254ff4fa46","repo":"chenhg5/cc-connect","slug":"unauthorized","errorCode":null,"errorMessage":"unauthorized","messagePattern":"unauthorized","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"core/bridge.go","lineNumber":737,"sourceCode":"\t// No CORS configured - require same-host (origin must match host)\n\thost := r.Host\n\tif host == \"\" {\n\t\thost = r.URL.Host\n\t}\n\t// Parse origin to get host\n\tif idx := strings.Index(origin, \"://\"); idx > 0 {\n\t\toriginHost := origin[idx+3:]\n\t\tif originHost == host {\n\t\t\treturn true\n\t\t}\n\t}\n\tslog.Warn(\"bridge: websocket origin mismatch\", \"origin\", origin, \"host\", host)\n\treturn false\n}\n\nfunc (bs *BridgeServer) handleWS(w http.ResponseWriter, r *http.Request) {\n\tif !bs.authenticate(r) {\n\t\thttp.Error(w, \"unauthorized\", http.StatusUnauthorized)\n\t\treturn\n\t}\n\n\t// Use a custom upgrader with origin checking\n\tupgrader := websocket.Upgrader{\n\t\tCheckOrigin: bs.checkOrigin,\n\t}\n\n\tconn, err := upgrader.Upgrade(w, r, nil)\n\tif err != nil {\n\t\tslog.Error(\"bridge: websocket upgrade failed\", \"error\", err)\n\t\treturn\n\t}\n\n\tslog.Info(\"bridge: new connection\", \"remote\", conn.RemoteAddr())\n\tbs.handleConnection(conn)\n}\n","sourceCodeStart":719,"sourceCodeEnd":755,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/bridge.go#L719-L755","documentation":"The bridge WebSocket endpoint rejects HTTP requests whose authentication check fails. `handleWS` calls `bs.authenticate(r)` before upgrading the connection; on failure it responds 401 with the plain body \"unauthorized\" and never upgrades. This protects the local bridge from unauthenticated clients connecting to the agent.","triggerScenarios":"Opening a WebSocket to the bridge server without the required auth credential, with a wrong or malformed token (e.g. missing Authorization header or query token), or with a token that does not match the configured bridge secret.","commonSituations":"Client configured with an outdated token after the bridge secret rotated; client omitting the token entirely; reverse proxy stripping the Authorization header; connecting a second tool to the bridge with a guessed/default token.","solutions":["Set the exact bridge token/secret configured on the BridgeServer in your client's Authorization header (or token query parameter, per authenticate()'s expected location).","Re-read the token from config.toml after any rotation and restart the client.","If behind a proxy, ensure the Authorization header is forwarded (e.g. proxy_set_header Authorization $http_authorization).","Enable debug logs on the bridge to see which auth path failed (missing vs mismatched credential)."],"exampleFix":"// before\nws := websocket.Dialer{}\nconn, _, err := ws.Dial(\"ws://127.0.0.1:8848/ws\", nil)\n// after\nhdr := http.Header{\"Authorization\": []string{\"Bearer \" + cfg.BridgeToken}}\nconn, resp, err := ws.Dial(\"ws://127.0.0.1:8848/ws\", hdr)\nif resp != nil && resp.StatusCode == http.StatusUnauthorized {\n    log.Fatal(\"bridge token mismatch — update BridgeToken\")\n}","handlingStrategy":"validation","validationCode":"func wsURL(u string, token string) error {\n    if u == \"\" || token == \"\" { return errors.New(\"bridge url and token required\") }\n    parsed, err := url.Parse(u)\n    if err != nil || (parsed.Scheme != \"ws\" && parsed.Scheme != \"wss\") { return errors.New(\"invalid ws url\") }\n    return nil\n}","typeGuard":"func isUnauthorized(resp *http.Response) bool { return resp != nil && resp.StatusCode == http.StatusUnauthorized }","tryCatchPattern":"conn, resp, err := dialer.Dial(url, authHeader)\nif err != nil {\n    if resp != nil && resp.StatusCode == 401 {\n        return fmt.Errorf(\"bridge auth failed: reload BridgeToken\")\n    }\n    return err\n}","preventionTips":["Load the bridge token from one shared config and reuse it in every client","Re-distribute tokens after any rotation via the same config file","Write a startup self-test that connects to the bridge WS and fails fast on 401","Verify proxies forward the Authorization header"],"tags":["websocket","authentication","http-401","bridge"],"backgroundTag":"authentication-required","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}