mirror of
https://github.com/coder/coder.git
synced 2026-09-21 20:51:01 +08:00
Subdomain app routing derived the app identity from httpapi.RequestHost, which returned the client-supplied X-Forwarded-Host header verbatim. No middleware validated or stripped that header, so a request from an untrusted peer could forge it. Since the application_connect cookie is scoped to the wildcard apps domain, JavaScript in a share=authenticated app could fetch() with a forged X-Forwarded-Host pointing at a victim's owner-only app; coderd routed and authorized the request as the victim and returned the private app response same-origin to the attacker. Replace RequestHost with httpmw.EffectiveHost, which honors X-Forwarded-Host only when the original socket peer is a configured trusted origin, otherwise falling back to the received Host header. This ties host trust to the same RealIPConfig model already used for X-Forwarded-For and -Proto. Wire it into HandleSubdomain for both coderd and wsproxy, and log both the effective host and the raw received_host. Add coverage: EffectiveHost unit tests assert the trust decision uses the socket peer rather than the spoofable forwarded client IP, and a HandleSubdomain test confirms a forged X-Forwarded-Host from an untrusted peer never reaches token resolution. Refs: https://linear.app/codercom/issue/PLAT-259
20 lines
361 B
Go
20 lines
361 B
Go
package httpapi
|
|
|
|
import "net/http"
|
|
|
|
const (
|
|
// XForwardedHostHeader is a header used by proxies to indicate the
|
|
// original host of the request.
|
|
XForwardedHostHeader = "X-Forwarded-Host"
|
|
)
|
|
|
|
func IsWebsocketUpgrade(r *http.Request) bool {
|
|
vs := r.Header.Values("Upgrade")
|
|
for _, v := range vs {
|
|
if v == "websocket" {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|