Major security leak PicketLink and testing on ADFSv2
pipo1000 Jun 24, 2010 4:54 AMHello,
I have tried to get PicketLink to work with Microsoft ADFSv2 and I have found a few issues and bugs with PicketLink. After
fixing these bugs and problems all seem to work well. You need to setup ADFSv2 so it will match PicketLink. With these changes PicketLink seems to work with ADFSv2. Only the POST profile seems to work, there is a problem with the redirect profile because ADFS answers the redirect request with a POST-profile anwser;
org.picketlink.identity.federation.bindings.tomcat.sp.SPPostSignatureFormAuthenticator
org.picketlink.identity.federation.bindings.tomcat.sp.SPPostFormAuthenticator
Claim:
SAM-Account-Name => Name ID
Token-Groups-Unqualified-Names => Role
Relying party identifier: https://webtest.personnelview.nl:8443/employee/
End-point to: https://webtest.personnelview.nl:8443/employee/
Advanced setting: SHA-1 (needed when you use the SPPostSignatureFormAuthenticator)
<IdentityURL>https://test4.nietdus.nl/adfs/ls/</IdentityURL>
<ServiceURL>https://webtest.personnelview.nl:8443/employee/</ServiceURL>
<KeyProvider ClassName="org.picketlink.identity.federation.core.impl.KeyStoreKeyManager">
<Auth Key="KeyStoreURL" Value="/jbid_test_keystore.jks" />
<Auth Key="KeyStorePass" Value="store123" />
<Auth Key="SigningKeyPass" Value="pipo" />
<Auth Key="SigningKeyAlias" Value="pipo" />
<ValidatingAlias Key="test4.nietdus.nl" Value="test4.nietdus.nl"/>
</KeyProvider>
You need a valid certificate with a valid root CA on your service provider, as ADFSv2 will check this!
- It looks like in SPPostSignatureFormAuthenticator the method verifySignature is never been called to verify the signing of the IDP (the SPFilter does check the signing of the IDP) !!! This is a very very big security leak!!!!
I have changed the SPPostFormAuthenticator so it will call the verifySignature method which is already present;
if(destination != null &&
samlResponseDocument != null)
{
sendRequestToIDP(destination, samlResponseDocument, relayState, response, willSendRequest);
}
else
{
// TODO EPD Check the signing of the IDP XML document
byte[] qbase64DecodedResponse = PostBindingUtil.base64Decode(samlResponse);
InputStream is = new ByteArrayInputStream(qbase64DecodedResponse);
SAML2Response qsaml2Response = new SAML2Response();
SAML2Object qsamlObject = qsaml2Response.getSAML2ObjectFromStream(is);
SAMLDocumentHolder documentHolder = qsaml2Response.getSamlDocumentHolder();
if(!verifySignature(documentHolder))
throw new ServletException("Cannot verify sender");
- ADFSv2 needs the Destination attribute with a AuthNRequest. The call saml2HandlerResponse.setDestination() is being set after the document has been formatted. I have changed the code so the identityURL has been passed on to the process;
saml2HandlerResponse = baseProcessor.process(httpContext, handlers, chainLock, identityURL);
- The IDP logout request still has a problem, it throws an error on ADFSv2. I have to look into this.
- The role response of ADFSv2 cannot be parsed correctly;
<AttributeStatement>
<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role">
<AttributeValue>Domain Users</AttributeValue>
<AttributeValue>manager</AttributeValue>
</Attribute>
To parse the response I have changed SAML2AuthenticationHandler to;
// Let us get the roles
AttributeStatementType attributeStatement = (AttributeStatementType) assertion.getStatementOrAuthnStatementOrAuthzDecisionStatement().get(0);
List<Object> attList = attributeStatement.getAttributeOrEncryptedAttribute();
for(Object obj:attList)
{
AttributeType attr = (AttributeType) obj;
List<Object> objects = attr.getAttributeValue() ;
for(Object o : objects)
{
if (o instanceof String)
{
// PicketLink IDP gives a string
String roleName = (String) o ;
roles.add(roleName);
}
else
{
// For ADFSv2 you can not cast it a String but you will get a NODE
Node n = (Node) o ;
Node value = n.getFirstChild() ;
String roleName = value.getNodeValue() ;
roles.add(roleName);
}
}
}
Hopefully you will add these changes to PicketLink, let me know if you need any more information!
Thanks,
Edwin