Skip to content

Commit 0edfe02

Browse files
committed
Validate Origin header on websocket connection upgrade
Prevent cross-origin websocket hijacking by validating the Origin header on websocket connection upgrade requests matches the target Host header. This means that a websocket connection can only be established from pages served from the same origin. (cherry picked from commit b22ba60)
1 parent 66fecf1 commit 0edfe02

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

pkg/router/router.go

+37-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2019-2021 The Tekton Authors
2+
Copyright 2019-2022 The Tekton Authors
33
Licensed under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License.
55
You may obtain a copy of the License at
@@ -172,7 +172,7 @@ func NewProxyHandler(apiProxyPrefix string, cfg *rest.Config, keepalive time.Dur
172172
proxy.UseRequestLocation = true
173173
proxy.UseLocationHost = true
174174

175-
proxyServer := http.Handler(proxy)
175+
proxyServer := protectWebSocket(proxy)
176176

177177
return proxyServer, nil
178178
}
@@ -191,3 +191,38 @@ func (s *Server) ServeOnListener(l net.Listener) error {
191191
}
192192
return server.Serve(l)
193193
}
194+
195+
// isUpgradeRequest returns true if the given request is a connection upgrade request
196+
func isUpgradeRequest(req *http.Request) bool {
197+
connection := req.Header.Get("Connection")
198+
return strings.ToLower(connection) == "upgrade"
199+
}
200+
201+
func checkUpgradeSameOrigin(req *http.Request) bool {
202+
host := req.Host
203+
origin := req.Header.Get("Origin")
204+
205+
if len(origin) == 0 || !isUpgradeRequest(req) {
206+
return true
207+
}
208+
209+
u, err := url.Parse(origin)
210+
if err != nil {
211+
return false
212+
}
213+
214+
return u.Host == host
215+
}
216+
217+
// Verify Origin header on Upgrade requests to prevent cross-origin websocket hijacking
218+
func protectWebSocket(h http.Handler) http.Handler {
219+
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
220+
if !checkUpgradeSameOrigin(req) {
221+
logging.Log.Warnf("websocket: Connection upgrade blocked, Host: %s, Origin: %s", req.Host, req.Header.Get("Origin"))
222+
http.Error(w, "websocket: request origin not allowed", http.StatusForbidden)
223+
return
224+
}
225+
226+
h.ServeHTTP(w, req)
227+
})
228+
}

0 commit comments

Comments
 (0)