diff --git a/cmd/admin/handlers/post.go b/cmd/admin/handlers/post.go index 78d63381..6fdc4e97 100644 --- a/cmd/admin/handlers/post.go +++ b/cmd/admin/handlers/post.go @@ -122,7 +122,20 @@ func (h *HandlersAdmin) QueryRunPOSTHandler(w http.ResponseWriter, r *http.Reque adminErrorResponse(w, "query can not be empty", http.StatusInternalServerError, nil) return } - // FIXME check if query is carve and user has permissions to carve + // Check if query is carve and user has permissions to carve + if queries.IsCarveQuery(q.Query) { + if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.CarveLevel, env.UUID) { + adminErrorResponse(w, fmt.Sprintf("%s has insufficient permissions to carve", ctx[sessions.CtxUser]), http.StatusForbidden, nil) + return + } + } + // Make sure the user has permissions to run queries in the environments + for _, e := range q.Environments { + if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.QueryLevel, e) { + adminErrorResponse(w, fmt.Sprintf("%s has insufficient permissions to run queries in environment %s", ctx[sessions.CtxUser], e), http.StatusForbidden, nil) + return + } + } // Prepare and create new query expTime := queries.QueryExpiration(q.ExpHours) if q.ExpHours == 0 { @@ -220,6 +233,13 @@ func (h *HandlersAdmin) CarvesRunPOSTHandler(w http.ResponseWriter, r *http.Requ adminErrorResponse(w, "path can not be empty", http.StatusInternalServerError, nil) return } + // Make sure the user has permissions to run queries in the environments + for _, e := range c.Environments { + if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.CarveLevel, e) { + adminErrorResponse(w, fmt.Sprintf("%s has insufficient permissions to run carves in environment %s", ctx[sessions.CtxUser], e), http.StatusForbidden, nil) + return + } + } // Set query expiration expTime := queries.QueryExpiration(c.ExpHours) if c.ExpHours == 0 { diff --git a/cmd/api/handlers/carves.go b/cmd/api/handlers/carves.go index c13a8da4..f505d4d2 100644 --- a/cmd/api/handlers/carves.go +++ b/cmd/api/handlers/carves.go @@ -189,6 +189,13 @@ func (h *HandlersApi) CarvesRunHandler(w http.ResponseWriter, r *http.Request) { apiErrorResponse(w, "path can not be empty", http.StatusInternalServerError, nil) return } + // Make sure the user has permissions to run queries in the environments + for _, e := range c.Environments { + if !h.Users.CheckPermissions(ctx[ctxUser], users.QueryLevel, e) { + apiErrorResponse(w, fmt.Sprintf("%s has insufficient permissions to run queries in environment %s", ctx[ctxUser], e), http.StatusForbidden, nil) + return + } + } expTime := queries.QueryExpiration(c.ExpHours) if c.ExpHours == 0 { expTime = time.Time{} diff --git a/cmd/api/handlers/queries.go b/cmd/api/handlers/queries.go index dc47e742..93afa0b6 100644 --- a/cmd/api/handlers/queries.go +++ b/cmd/api/handlers/queries.go @@ -111,6 +111,20 @@ func (h *HandlersApi) QueriesRunHandler(w http.ResponseWriter, r *http.Request) apiErrorResponse(w, "query can not be empty", http.StatusBadRequest, nil) return } + // Check if query is carve and user has permissions to carve + if queries.IsCarveQuery(q.Query) { + if !h.Users.CheckPermissions(ctx[ctxUser], users.CarveLevel, env.UUID) { + apiErrorResponse(w, fmt.Sprintf("%s has insufficient permissions to carve", ctx[ctxUser]), http.StatusForbidden, nil) + return + } + } + // Make sure the user has permissions to run queries in the environments + for _, e := range q.Environments { + if !h.Users.CheckPermissions(ctx[ctxUser], users.QueryLevel, e) { + apiErrorResponse(w, fmt.Sprintf("%s has insufficient permissions to run queries in environment %s", ctx[ctxUser], e), http.StatusForbidden, nil) + return + } + } expTime := queries.QueryExpiration(q.ExpHours) if q.ExpHours == 0 { expTime = time.Time{} diff --git a/pkg/queries/utils.go b/pkg/queries/utils.go index 1cf6c52c..07f6b5e9 100644 --- a/pkg/queries/utils.go +++ b/pkg/queries/utils.go @@ -1,6 +1,7 @@ package queries import ( + "strings" "time" "github.com/jmpsec/osctrl/pkg/utils" @@ -15,3 +16,8 @@ func GenQueryName() string { func QueryExpiration(exp int) time.Time { return time.Now().Add(time.Duration(exp) * time.Hour) } + +// Helper to check if query is carve +func IsCarveQuery(query string) bool { + return strings.Contains(strings.ToLower(query), "carves") +}