ccm,ocm: block API key headers from being forwarded upstream

This commit is contained in:
世界
2026-03-14 22:04:45 +08:00
parent 56af7313b2
commit bc6e72408d
13 changed files with 60 additions and 4 deletions

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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")

View File

@@ -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

View File

@@ -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")

View File

@@ -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")

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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")

View File

@@ -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

View File

@@ -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")

View File

@@ -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")

View File

@@ -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: