diff --git a/service/ccm/credential_default.go b/service/ccm/credential_default.go index a6ed7ec87..0bbf18874 100644 --- a/service/ccm/credential_default.go +++ b/service/ccm/credential_default.go @@ -715,7 +715,7 @@ func (c *defaultCredential) buildProxyRequest(ctx context.Context, original *htt } for key, values := range original.Header { - if !isHopByHopHeader(key) && !isReverseProxyHeader(key) && key != "Authorization" { + if !isHopByHopHeader(key) && !isReverseProxyHeader(key) && !isAPIKeyHeader(key) && key != "Authorization" { proxyRequest.Header[key] = values } } diff --git a/service/ccm/credential_external.go b/service/ccm/credential_external.go index eb75c5b08..a9876eaf5 100644 --- a/service/ccm/credential_external.go +++ b/service/ccm/credential_external.go @@ -371,7 +371,7 @@ func (c *externalCredential) buildProxyRequest(ctx context.Context, original *ht } for key, values := range original.Header { - if !isHopByHopHeader(key) && !isReverseProxyHeader(key) && key != "Authorization" { + if !isHopByHopHeader(key) && !isReverseProxyHeader(key) && !isAPIKeyHeader(key) && key != "Authorization" { proxyRequest.Header[key] = values } } diff --git a/service/ccm/reverse.go b/service/ccm/reverse.go index 97ef1751c..b6b4c88a0 100644 --- a/service/ccm/reverse.go +++ b/service/ccm/reverse.go @@ -57,6 +57,12 @@ func (s *Service) handleReverseConnect(ctx context.Context, w http.ResponseWrite return } + if r.Header.Get("X-Api-Key") != "" || r.Header.Get("Api-Key") != "" { + writeJSONError(w, r, http.StatusBadRequest, "invalid_request_error", + "API key authentication is not supported; use Authorization: Bearer with a CCM user token") + return + } + authHeader := r.Header.Get("Authorization") if authHeader == "" { writeJSONError(w, r, http.StatusUnauthorized, "authentication_error", "missing api key") diff --git a/service/ccm/service.go b/service/ccm/service.go index 69964c02c..043a147c1 100644 --- a/service/ccm/service.go +++ b/service/ccm/service.go @@ -139,6 +139,15 @@ func isReverseProxyHeader(header string) bool { } } +func isAPIKeyHeader(header string) bool { + switch strings.ToLower(header) { + case "x-api-key", "api-key": + return true + default: + return false + } +} + type Service struct { boxService.Adapter ctx context.Context diff --git a/service/ccm/service_handler.go b/service/ccm/service_handler.go index 7a59cfe4a..14ae3adeb 100644 --- a/service/ccm/service_handler.go +++ b/service/ccm/service_handler.go @@ -104,6 +104,12 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + if r.Header.Get("X-Api-Key") != "" || r.Header.Get("Api-Key") != "" { + writeJSONError(w, r, http.StatusBadRequest, "invalid_request_error", + "API key authentication is not supported; use Authorization: Bearer with a CCM user token") + return + } + var username string if len(s.options.Users) > 0 { authHeader := r.Header.Get("Authorization") diff --git a/service/ccm/service_status.go b/service/ccm/service_status.go index 75929c59f..cfc8c7635 100644 --- a/service/ccm/service_status.go +++ b/service/ccm/service_status.go @@ -20,6 +20,12 @@ func (s *Service) handleStatusEndpoint(w http.ResponseWriter, r *http.Request) { return } + if r.Header.Get("X-Api-Key") != "" || r.Header.Get("Api-Key") != "" { + writeJSONError(w, r, http.StatusBadRequest, "invalid_request_error", + "API key authentication is not supported; use Authorization: Bearer with a CCM user token") + return + } + authHeader := r.Header.Get("Authorization") if authHeader == "" { writeJSONError(w, r, http.StatusUnauthorized, "authentication_error", "missing api key") diff --git a/service/ocm/credential_default.go b/service/ocm/credential_default.go index 70b6eb6c1..18612a569 100644 --- a/service/ocm/credential_default.go +++ b/service/ocm/credential_default.go @@ -730,7 +730,7 @@ func (c *defaultCredential) buildProxyRequest(ctx context.Context, original *htt } for key, values := range original.Header { - if !isHopByHopHeader(key) && !isReverseProxyHeader(key) && key != "Authorization" { + if !isHopByHopHeader(key) && !isReverseProxyHeader(key) && !isAPIKeyHeader(key) && key != "Authorization" { proxyRequest.Header[key] = values } } diff --git a/service/ocm/credential_external.go b/service/ocm/credential_external.go index 02675780b..bcfe6d234 100644 --- a/service/ocm/credential_external.go +++ b/service/ocm/credential_external.go @@ -395,7 +395,7 @@ func (c *externalCredential) buildProxyRequest(ctx context.Context, original *ht } for key, values := range original.Header { - if !isHopByHopHeader(key) && !isReverseProxyHeader(key) && key != "Authorization" { + if !isHopByHopHeader(key) && !isReverseProxyHeader(key) && !isAPIKeyHeader(key) && key != "Authorization" { proxyRequest.Header[key] = values } } diff --git a/service/ocm/reverse.go b/service/ocm/reverse.go index 494cb4716..b47826e60 100644 --- a/service/ocm/reverse.go +++ b/service/ocm/reverse.go @@ -57,6 +57,12 @@ func (s *Service) handleReverseConnect(ctx context.Context, w http.ResponseWrite return } + if r.Header.Get("X-Api-Key") != "" || r.Header.Get("Api-Key") != "" { + writeJSONError(w, r, http.StatusBadRequest, "invalid_request_error", + "API key authentication is not supported; use Authorization: Bearer with an OCM user token") + return + } + authHeader := r.Header.Get("Authorization") if authHeader == "" { writeJSONError(w, r, http.StatusUnauthorized, "authentication_error", "missing api key") diff --git a/service/ocm/service.go b/service/ocm/service.go index 272bbb3a5..289152b64 100644 --- a/service/ocm/service.go +++ b/service/ocm/service.go @@ -152,6 +152,15 @@ func isReverseProxyHeader(header string) bool { } } +func isAPIKeyHeader(header string) bool { + switch strings.ToLower(header) { + case "x-api-key", "api-key": + return true + default: + return false + } +} + type Service struct { boxService.Adapter ctx context.Context diff --git a/service/ocm/service_handler.go b/service/ocm/service_handler.go index 1a247d6cc..905b1f5ae 100644 --- a/service/ocm/service_handler.go +++ b/service/ocm/service_handler.go @@ -80,6 +80,12 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + if r.Header.Get("X-Api-Key") != "" || r.Header.Get("Api-Key") != "" { + writeJSONError(w, r, http.StatusBadRequest, "invalid_request_error", + "API key authentication is not supported; use Authorization: Bearer with an OCM user token") + return + } + var username string if len(s.options.Users) > 0 { authHeader := r.Header.Get("Authorization") diff --git a/service/ocm/service_status.go b/service/ocm/service_status.go index 915fb837d..e32d8244e 100644 --- a/service/ocm/service_status.go +++ b/service/ocm/service_status.go @@ -20,6 +20,12 @@ func (s *Service) handleStatusEndpoint(w http.ResponseWriter, r *http.Request) { return } + if r.Header.Get("X-Api-Key") != "" || r.Header.Get("Api-Key") != "" { + writeJSONError(w, r, http.StatusBadRequest, "invalid_request_error", + "API key authentication is not supported; use Authorization: Bearer with an OCM user token") + return + } + authHeader := r.Header.Get("Authorization") if authHeader == "" { writeJSONError(w, r, http.StatusUnauthorized, "authentication_error", "missing api key") diff --git a/service/ocm/service_websocket.go b/service/ocm/service_websocket.go index 1b7b5baac..ce20e1be7 100644 --- a/service/ocm/service_websocket.go +++ b/service/ocm/service_websocket.go @@ -82,6 +82,8 @@ func isForwardableWebSocketRequestHeader(key string) bool { switch { case lowerKey == "authorization": return false + case lowerKey == "x-api-key" || lowerKey == "api-key": + return false case strings.HasPrefix(lowerKey, "sec-websocket-"): return false default: