Uploaded image for project: 'PicketLink'
  1. PicketLink
  2. PLINK-600

SAML2SignatureValidationHandler incorrectly identifying Redirect binding as POST

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • PLINK_2.7.0.CR1
    • PLINK_2.7.0.Beta2, PLINK_2.7.0.Final
    • SAML
    • None

      A recent change made to address this issue: PLINK-552 is causing the IDP to incorrectly identify incoming AuthnRequest requests over the Redirect binding as POST binding requests. This causes the signature validation to fail since Redirect bindings keep the signature data as params, not elements of the saml.

      The situation occurs when the AuthnRequest comes in over the Redirect Binding but requests the IdP to answer over the POST binding. This appears to be valid based on the saml-bindings-20 spec (section 3.4):
      Redirect "binding MAY be composed with the HTTP POST binding..."

      The new code (see https://github.com/pedroigor/picketlink/commit/ca9dc8a23e5dd8cd693270860f2341844cddb96c) uses a new way of determining if the incoming request is a Redirect or Post binding with the following function:

      from SAML2SignatureValidationHandler.java
      private boolean isPostBinding(SAML2HandlerRequest request, HTTPContext httpContext) {
        boolean isPost = httpContext.getRequest().getMethod().equalsIgnoreCase("POST");
        SAML2Object saml2Object = request.getSAML2Object();
       
        if (AuthnRequestType.class.isInstance(saml2Object)) {
           AuthnRequestType authnRequest = (AuthnRequestType) saml2Object;
           String authnRequestBinding = authnRequest.getProtocolBinding().toString();
       
           isPost = authnRequestBinding.equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get());
        }
       
        return isPost;
      }
      

      The above assumes that the ProtocolBinding of the incoming AuthnRequest is an attribute of the incoming request, but as defined by the saml-core-2.0 spec in section 3.4.1, it is:

      ProtocolBinding [Optional]
      A URI reference that identifies a SAML protocol binding to be used when returning the <Response> message

      With signatures required, this results in the following stacktrace:

      20:03:36,108 ERROR [] [] [org.picketlink.common] (JBossWeb-threads - 53) Error validating signature:: java.lang.RuntimeException: PL00092: Null Value:Cannot find Signature element
      	at org.picketlink.common.DefaultPicketLinkLogger.nullValueError(DefaultPicketLinkLogger.java:205) [picketlink-common-2.7.0-SNAPSHOT.jar:]
      	at org.picketlink.identity.federation.core.util.XMLSignatureUtil.validate(XMLSignatureUtil.java:498) [picketlink-federation-2.7.0-SNAPSHOT.jar:]
      	at org.picketlink.identity.federation.api.saml.v2.sig.SAML2Signature.validate(SAML2Signature.java:309) [picketlink-federation-2.7.0-SNAPSHOT.jar:]
      	at org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler.verifyPostBindingSignature(SAML2SignatureValidationHandler.java:147) [picketlink-federation-2.7.0-SNAPSHOT.jar:]
      	at org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler.validateSender(SAML2SignatureValidationHandler.java:86) [picketlink-federation-2.7.0-SNAPSHOT.jar:]
      	at org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler.handleRequestType(SAML2SignatureValidationHandler.java:55) [picketlink-federation-2.7.0-SNAPSHOT.jar:]
      	at org.picketlink.identity.federation.bindings.tomcat.idp.AbstractIDPValve.processSAMLRequestMessage(AbstractIDPValve.java:921) [picketlink-jbas7-2.7.0-SNAPSHOT.jar:2.7.0-SNAPSHOT]
      	at org.picketlink.identity.federation.bindings.tomcat.idp.AbstractIDPValve.handleSAMLMessage(AbstractIDPValve.java:491) [picketlink-jbas7-2.7.0-SNAPSHOT.jar:2.7.0-SNAPSHOT]
      	at org.picketlink.identity.federation.bindings.tomcat.idp.AbstractIDPValve.invoke(AbstractIDPValve.java:405) [picketlink-jbas7-2.7.0-SNAPSHOT.jar:2.7.0-SNAPSHOT]
      	at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
      	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
      	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
      	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
      	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
      	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
      	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
      	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:518) [jbossweb-7.0.13.Final.jar:]
      	at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33)
      	at org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:801)
      	at org.jboss.threads.QueueExecutor.access$100(QueueExecutor.java:45)
      	at org.jboss.threads.QueueExecutor$Worker.run(QueueExecutor.java:821)
      	at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_45]
      	at org.jboss.threads.JBossThread.run(JBossThread.java:122)
      
      

      The ProtocolBinding field should not be used for this since it is not attribute of the incoming request.

      The workaround for now is to use all POST bindings, which we will switch over to until this is addressed.

            psilva@redhat.com Pedro Igor Craveiro
            dividebyzero_jira Stefan Winz (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: