From ccb6dd7f1a823c99947f47cd8e8148871ef6f58e Mon Sep 17 00:00:00 2001 From: Oscar Zhou <100548325+oscarzhou-portainer@users.noreply.github.com> Date: Wed, 22 May 2024 09:08:51 +1200 Subject: [PATCH] fix(api/docker): no authorized user can call restricted api [EE-6808] (#11478) --- api/http/handler/docker/containers/handler.go | 3 ++- api/http/handler/docker/images/handler.go | 3 ++- api/http/middlewares/endpoint.go | 20 +++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/api/http/handler/docker/containers/handler.go b/api/http/handler/docker/containers/handler.go index c2bb79350..4446fdf79 100644 --- a/api/http/handler/docker/containers/handler.go +++ b/api/http/handler/docker/containers/handler.go @@ -7,6 +7,7 @@ import ( "github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/docker" dockerclient "github.com/portainer/portainer/api/docker/client" + "github.com/portainer/portainer/api/http/middlewares" "github.com/portainer/portainer/api/http/security" httperror "github.com/portainer/portainer/pkg/libhttp/error" ) @@ -30,7 +31,7 @@ func NewHandler(routePrefix string, bouncer security.BouncerService, dataStore d } router := h.PathPrefix(routePrefix).Subrouter() - router.Use(bouncer.AuthenticatedAccess) + router.Use(bouncer.AuthenticatedAccess, middlewares.CheckEndpointAuthorization(bouncer)) router.Handle("/{containerId}/gpus", httperror.LoggerHandler(h.containerGpusInspect)).Methods(http.MethodGet) router.Handle("/{containerId}/recreate", httperror.LoggerHandler(h.recreate)).Methods(http.MethodPost) diff --git a/api/http/handler/docker/images/handler.go b/api/http/handler/docker/images/handler.go index a6ff2fd16..aaf31827a 100644 --- a/api/http/handler/docker/images/handler.go +++ b/api/http/handler/docker/images/handler.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/portainer/portainer/api/docker/client" + "github.com/portainer/portainer/api/http/middlewares" "github.com/portainer/portainer/api/http/security" httperror "github.com/portainer/portainer/pkg/libhttp/error" @@ -25,7 +26,7 @@ func NewHandler(routePrefix string, bouncer security.BouncerService, dockerClien } router := h.PathPrefix(routePrefix).Subrouter() - router.Use(bouncer.AuthenticatedAccess) + router.Use(bouncer.AuthenticatedAccess, middlewares.CheckEndpointAuthorization(bouncer)) router.Handle("", httperror.LoggerHandler(h.imagesList)).Methods(http.MethodGet) return h diff --git a/api/http/middlewares/endpoint.go b/api/http/middlewares/endpoint.go index fa593fd41..c88731dd3 100644 --- a/api/http/middlewares/endpoint.go +++ b/api/http/middlewares/endpoint.go @@ -7,6 +7,7 @@ import ( portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/dataservices" + "github.com/portainer/portainer/api/http/security" httperror "github.com/portainer/portainer/pkg/libhttp/error" requesthelpers "github.com/portainer/portainer/pkg/libhttp/request" @@ -63,3 +64,22 @@ func FetchEndpoint(request *http.Request) (*portainer.Endpoint, error) { return contextData.(*portainer.Endpoint), nil } + +func CheckEndpointAuthorization(bouncer security.BouncerService) mux.MiddlewareFunc { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + endpoint, err := FetchEndpoint(r) + if err != nil { + httperror.WriteError(w, http.StatusNotFound, "Unable to find an environment on request context", err) + return + } + + if err = bouncer.AuthorizedEndpointOperation(r, endpoint); err != nil { + httperror.WriteError(w, http.StatusForbidden, "Permission denied to access environment", err) + return + } + + next.ServeHTTP(w, r) + }) + } +}