Files
lijiaoqiao/platform-token-runtime/internal/auth/middleware/query_key_reject_middleware.go
Your Name ad776e4079 fix: P0/P1 security fixes across gateway, token-runtime, and supply-api
P0 fixes:
- platform-token-runtime: Add store.Save() after Refresh token update (P0-3)
- platform-token-runtime: Add sync.RWMutex to InMemoryRuntimeStore (P0-4)
- platform-token-runtime: Add bearer token auth to /audit-events endpoint (P0-5)
- gateway: Fail startup in production if PASSWORD_ENCRYPTION_KEY uses default (P0-1)
- gateway: Require explicit CORS_ALLOW_ORIGINS in production (P0-2)

P1 fixes:
- gateway: Add TrustedProxies config field + env var GATEWAY_TRUSTED_PROXIES (P1-5)
- gateway: Sanitize X-Request-ID header to prevent log injection (P1-6)
- gateway: Strip internal error details from error responses to clients (P1-7)
- supply-api: Upgrade deriveDEK from trivial byte-rotation to HKDF-SHA256 (P1-1)
- supply-api: Reject HS256/HS384/HS512 in production, require RSA (P1-2)

Code quality fixes:
- supply-api: Add BruteForceMaxAttempts + BruteForceLockoutDuration to AuthConfig (MED-12)
- supply-api: Add TrustedProxies to token_auth_middleware (IP spoofing protection)
- supply-api: Use shared pathutil.SplitPath instead of duplicate splitPath
- supply-api: Fix query_key_reject_middleware call sites with trustedProxies param
- gateway: Wire TrustedProxies into AuthMiddlewareConfig and extractClientIP
- gateway: Add CORSAllowOrigins to AuthConfig, wire into CORSMiddleware
- gateway: Fix CompletionsHandle to have context and RecordResult like ChatCompletions
- gateway: Add sanitizeRequestID helper for X-Request-ID log injection prevention
- gateway: Add os import for PASSWORD_ENCRYPTION_KEY check
- gateway: Add strings import to handler.go for sanitizeRequestID

Environment issues documented in TEST_ENVIRONMENT_ISSUES.md
2026-04-17 14:36:02 +08:00

52 lines
1.3 KiB
Go

package middleware
import (
"net/http"
"strings"
"time"
"lijiaoqiao/platform-token-runtime/internal/auth/service"
)
var disallowedQueryKeys = []string{"key", "api_key", "token"}
func QueryKeyRejectMiddleware(next http.Handler, auditor service.AuditEmitter, now func() time.Time, trustedProxies []string) http.Handler {
if next == nil {
next = http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})
}
if now == nil {
now = defaultNowFunc
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, exists := externalQueryKey(r)
if !exists {
next.ServeHTTP(w, r)
return
}
requestID := ensureRequestID(r, now)
emitAuditEvent(r.Context(), auditor, service.AuditEvent{
EventName: service.EventTokenQueryKeyRejected,
RequestID: requestID,
Route: r.URL.Path,
ResultCode: service.CodeQueryKeyNotAllowed,
ClientIP: extractClientIP(r, trustedProxies),
CreatedAt: now(),
})
writeError(w, http.StatusUnauthorized, requestID, service.CodeQueryKeyNotAllowed, "query key ingress is not allowed")
})
}
func externalQueryKey(r *http.Request) (string, bool) {
values := r.URL.Query()
for key := range values {
lowered := strings.ToLower(key)
for _, disallowed := range disallowedQueryKeys {
if lowered == disallowed {
return key, true
}
}
}
return "", false
}