The following security issue was reported to Red Hat Product Security.
Example: configure the PicketLink IDP to require a role ("manager") for all resources ("/*").
<security-constraint> <web-resource-collection> <web-resource-name>Manager command</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> <role-name>Sales</role-name> <role-name>Employee</role-name> </auth-constraint> </security-constraint>
Access the IDP (http://localhost:8080/idp/) and log in as user not a member of manager, Sales, or Employee roles. The server returns index.html.
An authenticated user that is not a member of any of those roles is able to view a file located in /hosted/index.jsp or a file specified by HostedURI in the IDP configuration:
<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1"> <PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:2.1" HostedURI="/test.jsp" AttributeManager="org.picketlink.identity.federation.bindings.jboss.attribute.JBossAppServerAttributeManager"
If the PicketLink IDP is accessed in a SP initiated flow, then an unauthorized user is also able to generate a valid SAMLResponse and get redirected back to the SP. The roles appear to be checked correctly at the SP, but the IDP should have returned a 403 error.
The issue appears to be that the PicketLink IDP code does not check for proper authorization after the FormAuthenticator has been invoked in the chain. The PicketLink IDP valve is invoked first in the chain, then the FormAuthenticator is invoked. Once control is returned back to the PicketLink IDP valve, it does not check for proper authorization before returning the HostedURI or the SAMLResponse. Adding the following check appears to resolve the issue:
picketlink-tomcat-common/src/main/java/org/picketlink/identity/federation/bindings/tomcat/idp/AbstractIDPValve.java @@ -384,6 +384,11 @@ public abstract class AbstractIDPValve extends ValveBase {
invokeNextValve(request, response);
+ if (isUnauthorized(response)) { + System.out.println("**** unauthorized!!"); + return; + }
+ userPrincipal = request.getUserPrincipal();
|