From a914dee6d908534952c9cb25cfcb53f18a15c304 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Fri, 30 Aug 2013 16:24:24 +0200 Subject: [PATCH] FIX Disallow permissions assign for APPLY_ROLES (SS-2013-005) See http://www.silverstripe.org/ss-2013-005-privilege-escalation-through-apply-roles-assignment/ --- security/PermissionCheckboxSetField.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/security/PermissionCheckboxSetField.php b/security/PermissionCheckboxSetField.php index f93d94eb0..48ccca6c7 100644 --- a/security/PermissionCheckboxSetField.php +++ b/security/PermissionCheckboxSetField.php @@ -193,6 +193,11 @@ class PermissionCheckboxSetField extends FormField { // show its origin automatically $inheritMessage = ' (' . join(', ', $uninheritedCodes[$code]).')'; } + + // Disallow modification of "privileged" permissions unless currently logged-in user is an admin + if(!Permission::check('ADMIN') && in_array($code, Permission::$privileged_permissions)) { + $disabled = ' disabled="true"'; + } // If the field is readonly, always mark as "disabled" if($this->readonly) $disabled = ' disabled="true"'; @@ -218,6 +223,16 @@ class PermissionCheckboxSetField extends FormField { $fieldname = $this->name; $managedClass = $this->managedClass; + // Remove all "privileged" permissions if the currently logged-in user is not an admin + if(!Permission::check('ADMIN')) { + foreach($this->value as $id => $bool) { + if(in_array($id, Permission::$privileged_permissions)) { + unset($this->value[$id]); + } + } + } + + // remove all permissions and re-add them afterwards $permissions = $record->$fieldname(); foreach ( $permissions as $permission ) {