Skip to content

Commit

Permalink
Validate Origin header on websocket connection upgrade
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
AlanGreene committed Apr 4, 2022
1 parent 66fecf1 commit 0edfe02
Showing 1 changed file with 37 additions and 2 deletions.
39 changes: 37 additions & 2 deletions pkg/router/router.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2021 The Tekton Authors
Copyright 2019-2022 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand Down Expand Up @@ -172,7 +172,7 @@ func NewProxyHandler(apiProxyPrefix string, cfg *rest.Config, keepalive time.Dur
proxy.UseRequestLocation = true
proxy.UseLocationHost = true

proxyServer := http.Handler(proxy)
proxyServer := protectWebSocket(proxy)

return proxyServer, nil
}
Expand All @@ -191,3 +191,38 @@ func (s *Server) ServeOnListener(l net.Listener) error {
}
return server.Serve(l)
}

// isUpgradeRequest returns true if the given request is a connection upgrade request
func isUpgradeRequest(req *http.Request) bool {
connection := req.Header.Get("Connection")
return strings.ToLower(connection) == "upgrade"
}

func checkUpgradeSameOrigin(req *http.Request) bool {
host := req.Host
origin := req.Header.Get("Origin")

if len(origin) == 0 || !isUpgradeRequest(req) {
return true
}

u, err := url.Parse(origin)
if err != nil {
return false
}

return u.Host == host
}

// Verify Origin header on Upgrade requests to prevent cross-origin websocket hijacking
func protectWebSocket(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if !checkUpgradeSameOrigin(req) {
logging.Log.Warnf("websocket: Connection upgrade blocked, Host: %s, Origin: %s", req.Host, req.Header.Get("Origin"))
http.Error(w, "websocket: request origin not allowed", http.StatusForbidden)
return
}

h.ServeHTTP(w, req)
})
}

0 comments on commit 0edfe02

Please sign in to comment.