From 32a498e04f265756fb1583f57f3f55f64830b3a7 Mon Sep 17 00:00:00 2001 From: Gabriel MABILLE Date: Wed, 30 Nov 2022 13:55:07 +0100 Subject: [PATCH] RBAC: Validate plugin app access permission targets the plugin (#59468) * RBAC: Validate plugin app access permission targets the plugin * Fix service test --- pkg/services/accesscontrol/acimpl/service_test.go | 2 +- pkg/services/accesscontrol/errors.go | 14 ++++++++++++++ pkg/services/accesscontrol/pluginutils/utils.go | 5 +++++ .../accesscontrol/pluginutils/utils_test.go | 13 ++++++++++++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pkg/services/accesscontrol/acimpl/service_test.go b/pkg/services/accesscontrol/acimpl/service_test.go index c635d506e91..09bd7435afa 100644 --- a/pkg/services/accesscontrol/acimpl/service_test.go +++ b/pkg/services/accesscontrol/acimpl/service_test.go @@ -189,7 +189,7 @@ func TestService_DeclarePluginRoles(t *testing.T) { Role: plugins.Role{ Name: "Tester", Permissions: []plugins.Permission{ - {Action: "plugins.app:access"}, + {Action: "plugins.app:access", Scope: "plugins:id:test-app"}, {Action: "test-app:read"}, {Action: "test-app.resource:read"}, }, diff --git a/pkg/services/accesscontrol/errors.go b/pkg/services/accesscontrol/errors.go index 91f06a38440..27047abb596 100644 --- a/pkg/services/accesscontrol/errors.go +++ b/pkg/services/accesscontrol/errors.go @@ -44,3 +44,17 @@ func (e *ErrorActionPrefixMissing) Error() string { func (e *ErrorActionPrefixMissing) Unwrap() error { return &ErrorInvalidRole{} } + +type ErrorScopeTarget struct { + Action string + Scope string + ExpectedScope string +} + +func (e *ErrorScopeTarget) Error() string { + return fmt.Sprintf("expected action '%s' to be scoped with '%v', found '%v'", e.Action, e.ExpectedScope, e.Scope) +} + +func (e *ErrorScopeTarget) Unwrap() error { + return &ErrorInvalidRole{} +} diff --git a/pkg/services/accesscontrol/pluginutils/utils.go b/pkg/services/accesscontrol/pluginutils/utils.go index eac5effdcf0..b246706668f 100644 --- a/pkg/services/accesscontrol/pluginutils/utils.go +++ b/pkg/services/accesscontrol/pluginutils/utils.go @@ -17,6 +17,11 @@ func ValidatePluginPermissions(pluginID string, permissions []ac.Permission) err return &ac.ErrorActionPrefixMissing{Action: permissions[i].Action, Prefixes: []string{plugins.ActionAppAccess, pluginID + ":", pluginID + "."}} } + if strings.HasPrefix(permissions[i].Action, plugins.ActionAppAccess) && + permissions[i].Scope != plugins.ScopeProvider.GetResourceScope(pluginID) { + return &ac.ErrorScopeTarget{Action: permissions[i].Action, Scope: permissions[i].Scope, + ExpectedScope: plugins.ScopeProvider.GetResourceScope(pluginID)} + } } return nil diff --git a/pkg/services/accesscontrol/pluginutils/utils_test.go b/pkg/services/accesscontrol/pluginutils/utils_test.go index 8722c8e747a..0284ebbb49e 100644 --- a/pkg/services/accesscontrol/pluginutils/utils_test.go +++ b/pkg/services/accesscontrol/pluginutils/utils_test.go @@ -122,12 +122,23 @@ func TestValidatePluginRole(t *testing.T) { role: ac.RoleDTO{ Name: "plugins:test-app:reader", Permissions: []ac.Permission{ - {Action: "plugins.app:access"}, + {Action: "plugins.app:access", Scope: "plugins:id:test-app"}, {Action: "test-app:read"}, {Action: "test-app.resources:read"}, }, }, }, + { + name: "invalid permission targets other plugin", + pluginID: "test-app", + role: ac.RoleDTO{ + Name: "plugins:test-app:reader", + Permissions: []ac.Permission{ + {Action: "plugins.app:access", Scope: "plugins:id:other-app"}, + }, + }, + wantErr: &ac.ErrorInvalidRole{}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {