秋田预测市场 · Discord 审计

WebSocket API 生产环境 Origin 标头导致 403 错误

2026-07-09 · Kalshi · 10 条相关讨论

Ghibli 2026-07-09 06:39:30

When connecting to the websocket API, if an `Origin:` header is set then the websocket API returns a forbidden HTTP status code. The demo environment does not demonstrate this behavior. This is a bit problematic for us because the default golang websocket library sets this header: https://cs.opensource.google/go/x/net/+/refs/tags/v0.56.0:websocket/hybi.go;l=418 1) Maybe there's a valid Origin value that we can set that will not trigger a forbidden in production? 2) It would be helpful to keep the behavior in sync between demo and production websocket environments so that they both either return a forbidden or don't, when the header is set Thanks!

When connecting to the websocket API, if an `Origin:` header is set then the websocket API returns a forbidden HTTP status code. The demo environment does not demonstrate this behavior. This is a bit problematic for us because the default golang websocket library sets this header: https://cs.opensource.google/go/x/net/+/refs/tags/v0.56.0:websocket/hybi.go;l=418 1) Maybe there's a valid Origin value that we can set that will not trigger a forbidden in production? 2) It would be helpful to keep the behavior in sync between demo and production websocket environments so that they both either return a forbidden or don't, when the header is set Thanks!

VOXindie 2026-07-09 06:41:52

Can you not clear the header?

Can you not clear the header?

Ghibli 2026-07-09 06:43:15

The header cannot be cleared The library code requires some value

The header cannot be cleared The library code requires some value

VOXindie 2026-07-09 06:43:31

Is this not valid? ``` package main import ( "net/http" "net/url" "github.com/gorilla/websocket" ) func main() { u := url.URL{Scheme: "ws", Host: "example.com", Path: "/ws"} // Set a custom Origin header (or leave it blank) headers := http.Header{} headers.Set("Origin", "") // Clears/omits the default origin dialer := websocket.Dialer{} c, resp, err := dialer.Dial(u.String(), headers) // ... } ```

Is this not valid? ``` package main import ( "net/http" "net/url" "github.com/gorilla/websocket" ) func main() { u := url.URL{Scheme: "ws", Host: "example.com", Path: "/ws"} // Set a custom Origin header (or leave it blank) headers := http.Header{} headers.Set("Origin", "") // Clears/omits the default origin dialer := websocket.Dialer{} c, resp, err := dialer.Dial(u.String(), headers) // ... } ```

VOXindie 2026-07-09 06:45:47

You could try setting the origin to the Kalshi URL.

You could try setting the origin to the Kalshi URL.

Ghibli 2026-07-09 06:46:42

Yep, I tried all variations of that, I couldn't find a header that worked in production

Yep, I tried all variations of that, I couldn't find a header that worked in production

VOXindie 2026-07-09 06:47:22

Good luck then 😛 I would probably upgrade to a more modern library. Even the docs suggest using gorilla lol https://pkg.go.dev/golang.org/x/net/websocket

Good luck then 😛 I would probably upgrade to a more modern library. Even the docs suggest using gorilla lol https://pkg.go.dev/golang.org/x/net/websocket

Ghibli 2026-07-09 06:54:05

We don't want to take on an additional dependency if we don't have to (see: supply chain attacks). We don't need anything else provided by gorilla/websocket, the built-in library works for us in terms of features and functionality. is it expected that there's inconsistent behavior between the handling of `Origin` headers in the production websocket API endpoint and demo websocket API endpoint?

We don't want to take on an additional dependency if we don't have to (see: supply chain attacks). We don't need anything else provided by gorilla/websocket, the built-in library works for us in terms of features and functionality. is it expected that there's inconsistent behavior between the handling of `Origin` headers in the production websocket API endpoint and demo websocket API endpoint?

VOXindie 2026-07-09 06:58:13

It is expected that demo is trash and nobody really uses it lol

It is expected that demo is trash and nobody really uses it lol

Ghibli 2026-07-09 07:00:58

Good to know

Good to know