Grouper has a bug which allows unauthorized users to see the group and folder privileges (e.g. ADMIN/UPDATE/READ/etc on a group or STEM/CREATE on a folder) for any subject. So for example, if a user has UPDATE privileges on a group, typically only admins of the group would be able to see that. But with this bug, anybody that can access the Grouper UI can see that the user has UPDATE on the group. This bug does not expose the memberships of subjects.
This bug affects v1.4, v1.5, v1.6, v2.0, and v2.1 (up to 2.1.4). The bug is fixed in each of the branches and included in 2.1.5. The bug probably exists in v1.3 and before, but has not been confirmed or fixed in those old releases. This patch can be applied to v1.4.0+.
subjectIdAuthenticating = "test.subject.0"; // you will authenticate to the Grouper UI as this subject subjectIdCheckPrivileges = "test.subject.1"; // you will check privileges for this subject grouperSession = GrouperSession.startRootSession(); subjectAuthenticating = SubjectFinder.findByIdOrIdentifier(subjectIdAuthenticating, true); subjectCheckingPrivileges = SubjectFinder.findByIdOrIdentifier(subjectIdCheckPrivileges, true); groupNameCanViewPrivs = "test:testUIPrivilegeIssue:groupCanViewPrivs"; groupNameCannotViewPrivs = "test:testUIPrivilegeIssue:groupCannotViewPrivs"; folderNameCanViewPrivs = "test:testUIPrivilegeIssue:folderCanViewPrivs"; folderNameCannotViewPrivs = "test:testUIPrivilegeIssue:folderCannotViewPrivs"; groupCanViewPrivs = new GroupSave(grouperSession).assignName(groupNameCanViewPrivs).assignCreateParentStemsIfNotExist(true).save(); groupCannotViewPrivs = new GroupSave(grouperSession).assignName(groupNameCannotViewPrivs).assignCreateParentStemsIfNotExist(true).save(); folderCanViewPrivs = new StemSave(grouperSession).assignName(folderNameCanViewPrivs).save(); folderCannotViewPrivs = new StemSave(grouperSession).assignName(folderNameCannotViewPrivs).save(); groupCanViewPrivs.grantPriv(subjectAuthenticating, AccessPrivilege.ADMIN); groupCanViewPrivs.grantPriv(subjectCheckingPrivileges, AccessPrivilege.UPDATE); groupCannotViewPrivs.grantPriv(subjectCheckingPrivileges, AccessPrivilege.UPDATE); folderCanViewPrivs.grantPriv(subjectAuthenticating, NamingPrivilege.STEM); folderCanViewPrivs.grantPriv(subjectCheckingPrivileges, NamingPrivilege.CREATE); folderCannotViewPrivs.grantPriv(subjectCheckingPrivileges, NamingPrivilege.CREATE); |
Now reproduce the issue using the Grouper UI.
You need to edit PopulateSubjectSummaryAction.java. Note, these instructions are tomcat-specific. Note, anytime you see /PATH_TO_GROUPER_UI_TOMCAT/ substitute that for the path to that tomcat, and anytime you see grouperUiAppName, substitute that for the app name you use for grouper UI, which is generally grouper.
Unzip the grouper-ui.jar file in a location where you can compile a classfile. These instructions are for linux, though could be used in windows if you change the path separators (colon to semicolon)
$ mkdir /tmp/grouperUiPrivPatch $ cd /tmp/grouperUiPrivPatch/ $ mkdir temp $ unzip /PATH_TO_GROUPER_UI_TOMCAT/webapps/grouperUiAppName/WEB-INF/lib/grouper-ui.jar -d temp $ mkdir -p edu/internet2/middleware/grouper/ui/actions/ $ cp temp/edu/internet2/middleware/grouper/ui/actions/PopulateSubjectSummaryAction.java edu/internet2/middleware/grouper/ui/actions/ $ rm -rf temp $ vi edu/internet2/middleware/grouper/ui/actions/PopulateSubjectSummaryAction.java |
There are two method calls to GrouperHelper.getGroupsOrStemsWhereMemberHasPriv(). We're going to filter the results to remove groups/folders that the person shouldn't be able to see.
First, replace the following:
subjectScopes = GrouperHelper.getGroupsOrStemsWhereMemberHasPriv(member,accessPriv); |
with this:
subjectScopes = GrouperHelper.getGroupsOrStemsWhereMemberHasPriv(member,accessPriv); // filter out groups where the subject can't see privs removeObjectsNotAllowedToSeePrivs(subjectScopes); |
Second, replace the following:
subjectScopes = GrouperHelper.getGroupsOrStemsWhereMemberHasPriv(member,namingPriv); |
with this:
subjectScopes = GrouperHelper.getGroupsOrStemsWhereMemberHasPriv(member,namingPriv); // filter out stems where the subject can't see privs removeObjectsNotAllowedToSeePrivs(subjectScopes); |
And third, add the following method at the end:
/** * remove objects not allowed to see privileges on * @param groupsAndStems */ public static void removeObjectsNotAllowedToSeePrivs(Set<?> groupsAndStems) { if (groupsAndStems == null) { return; } //subject who is making the query final Subject grouperSessionSubject = GrouperSession.staticGrouperSession().getSubject(); java.util.Iterator<?> iterator = groupsAndStems.iterator(); while (iterator.hasNext()) { Object groupOrStem = iterator.next(); if (groupOrStem instanceof edu.internet2.middleware.grouper.Group) { edu.internet2.middleware.grouper.Group group = (edu.internet2.middleware.grouper.Group)groupOrStem; if (!group.hasAdmin(grouperSessionSubject)) { iterator.remove(); } } else if (groupOrStem instanceof edu.internet2.middleware.grouper.Stem) { edu.internet2.middleware.grouper.Stem stem = (edu.internet2.middleware.grouper.Stem)groupOrStem; if (!stem.hasStem(grouperSessionSubject)) { iterator.remove(); } } else { //this should never happen throw new RuntimeException("Not expecting object of type: " + groupOrStem.getClass() + ", " + groupOrStem); } } } |
Compile the patched file, note, if you are using Java previous to 1.6, then you need to list out the jar files, instead of the asterisk. Install, and bounce tomcat
$ javac -classpath "/PATH_TO_GROUPER_UI_TOMCAT/webapps/grouperUiAppName/WEB-INF/lib/*:/PATH_TO_GROUPER_UI_TOMCAT/lib/*" -sourcepath . edu/internet2/middleware/grouper/ui/actions/PopulateSubjectSummaryAction.java $ $ find . -name PopulateSubjectSummaryAction* ./edu/internet2/middleware/grouper/ui/actions/PopulateSubjectSummaryAction.class ./edu/internet2/middleware/grouper/ui/actions/PopulateSubjectSummaryAction.java $ $ cp -R edu /PATH_TO_GROUPER_UI_TOMAT/webapps/grouperUiAppName/WEB-INF/classes/ $ find /PATH_TO_GROUPER_UI_TOMAT/webapps/grouperUiAppName/WEB-INF/classes/edu -name PopulateSubjectSummaryAction* /PATH_TO_GROUPER_UI_TOMAT/webapps/grouperUiAppName/WEB-INF/classes/edu/internet2/middleware/grouper/ui/actions/PopulateSubjectSummaryAction.class /PATH_TO_GROUPER_UI_TOMAT/webapps/grouperUiAppName/WEB-INF/classes/edu/internet2/middleware/grouper/ui/actions/PopulateSubjectSummaryAction.java |
Note, if you run on a cluster, you should zip up the files in the patch, and copy them to all servers that need them. Make sure the path is grouperUiAppName/WEB-INF/classes/edu/internet2... Also, you should probably copy the source file and the classfiles in case there are further tweaks.
Bounce tomcat.
Test that the patch worked.