diff --git a/app/admin/admin.go b/app/admin/admin.go index 5a5f499..61b9f36 100644 --- a/app/admin/admin.go +++ b/app/admin/admin.go @@ -6,6 +6,7 @@ package admin import ( "context" + "crypto/subtle" "encoding/json" "net/http" "os" @@ -119,8 +120,12 @@ func (h *Handler) RegisterPublicRoutes(r *mux.Router) { func (h *Handler) bearerAuthMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { authHeader := r.Header.Get("Authorization") + // Timing-safe сравнение: длина префикса и сам токен проверяются отдельно, + // само сравнение значения — через subtle.ConstantTimeCompare, чтобы не + // давать timing side-channel при подборе admin-токена. expected := "Bearer " + h.adminToken - if authHeader != expected { + if len(authHeader) != len(expected) || + subtle.ConstantTimeCompare([]byte(authHeader), []byte(expected)) != 1 { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) json.NewEncoder(w).Encode(map[string]string{"error": "unauthorized"})