From 091c096dbf0148592c9ca54228169723e120cb32 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Fri, 30 Aug 2013 16:27:58 +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 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/security/PermissionCheckboxSetField.php b/security/PermissionCheckboxSetField.php index 0c2ca25f6..d3b7ab151 100644 --- a/security/PermissionCheckboxSetField.php +++ b/security/PermissionCheckboxSetField.php @@ -162,6 +162,8 @@ class PermissionCheckboxSetField extends FormField { $options = ''; $globalHidden = (array)Config::inst()->get('Permission', 'hidden_permissions'); if($this->source) { + $privilegedPermissions = Permission::config()->privileged_permissions; + // loop through all available categorized permissions and see if they're assigned for the given groups foreach($this->source as $categoryName => $permissions) { $options .= "
  • $categoryName
  • "; @@ -194,6 +196,11 @@ class PermissionCheckboxSetField extends FormField { $inheritMessage = ' (' . join(', ', $uninheritedCodes[$code]).')'; } + // Disallow modification of "privileged" permissions unless currently logged-in user is an admin + if(!Permission::check('ADMIN') && in_array($code, $privilegedPermissions)) { + $disabled = ' disabled="true"'; + } + // If the field is readonly, always mark as "disabled" if($this->readonly) $disabled = ' disabled="true"'; @@ -246,6 +253,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 + $privilegedPermissions = Permission::config()->privileged_permissions; + if(!Permission::check('ADMIN')) { + foreach($this->value as $id => $bool) { + if(in_array($id, $privilegedPermissions)) { + unset($this->value[$id]); + } + } + } + // remove all permissions and re-add them afterwards $permissions = $record->$fieldname(); foreach ( $permissions as $permission ) {