Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

BUGFIX Avoid privilege escalation from EDIT_PERMISSIONS to ADMIN thro…

…ugh TreeMultiselectField (in Member->getCMSFields()) by checking for admin groups in Member->onChangeGroups()
  • Loading branch information...
commit de1f07045ba35273174907404c92aa0e9d7f1d9a 1 parent 5d87f29
@chillu chillu authored
Showing with 47 additions and 0 deletions.
  1. +18 −0 security/Member.php
  2. +29 −0 tests/security/MemberTest.php
View
18 security/Member.php
@@ -693,6 +693,24 @@ function onAfterWrite() {
MemberPassword::log($this);
}
}
+
+ /**
+ * If any admin groups are requested, deny the whole save operation.
+ *
+ * @param Array $ids Database IDs of Group records
+ * @return boolean
+ */
+ function onChangeGroups($ids) {
+ // Filter out admin groups to avoid privilege escalation,
+ // unless the current user is an admin already
+ if(!Permission::checkMember($this, 'ADMIN')) {
+ $adminGroups = Permission::get_groups_by_permission('ADMIN');
+ $adminGroupIDs = ($adminGroups) ? $adminGroups->column('ID') : array();
+ return count(array_intersect($ids, $adminGroupIDs)) == 0;
+ } else {
+ return true;
+ }
+ }
/**
View
29 tests/security/MemberTest.php
@@ -527,6 +527,35 @@ function testMembersWithSecurityAdminAccessCantEditAdminsUnlessTheyreAdminsThems
$this->assertFalse($adminMember->canEdit($securityAdminMember), 'Security-Admins can not edit other admins');
$this->assertTrue($ceoMember->canEdit($securityAdminMember), 'Security-Admins can edit other members');
}
+
+ function testOnChangeGroups() {
+ $staffGroup = $this->objFromFixture('Group', 'staffgroup');
+ $adminGroup = $this->objFromFixture('Group', 'admingroup');
+ $staffMember = $this->objFromFixture('Member', 'staffmember');
+ $adminMember = $this->objFromFixture('Member', 'admin');
+ $newAdminGroup = new Group(array('Title' => 'newadmin'));
+ $newAdminGroup->write();
+ Permission::grant($newAdminGroup->ID, 'ADMIN');
+ $newOtherGroup = new Group(array('Title' => 'othergroup'));
+ $newOtherGroup->write();
+
+ $this->assertTrue(
+ $staffMember->onChangeGroups(array($staffGroup->ID)),
+ 'Adding existing non-admin group relation is allowed for non-admin members'
+ );
+ $this->assertTrue(
+ $staffMember->onChangeGroups(array($newOtherGroup->ID)),
+ 'Adding new non-admin group relation is allowed for non-admin members'
+ );
+ $this->assertFalse(
+ $staffMember->onChangeGroups(array($newAdminGroup->ID)),
+ 'Adding new admin group relation is not allowed for non-admin members'
+ );
+ $this->assertTrue(
+ $adminMember->onChangeGroups(array($newAdminGroup->ID)),
+ 'Adding new admin group relation is allowed for admin members'
+ );
+ }
/**
* Add the given array of member extensions as class names.
Please sign in to comment.
Something went wrong with that request. Please try again.