single-sign-onsigningsaml-2.0shibbolethservice-provider

Should I require IdP's to sign SAML2 SSO responses?


Our app has SAML2 SSO integration with 3 different (Shibboleth) IdP's. We are trying to add a 4th (also Shibboleth), but running into some issues, because our app expects all SSO responses to be verifiably signed. These other 3 are signing their responses, but the 4th is not, and is hesitant to add a custom config to enforce signing for our app.

Technically I could modify our app to accept unsigned SSO responses, but I am wondering whether or not I should. What are the pitfalls of allowing unsigned SSO responses? Is there any security vulnerability?

Is there any Shibboleth (or other SAML2 SSO) documentation that recommends signing responses as a best practice?


Solution

  • Signing Assertion(s)

    The only requirement for the IdP following the SAML 2.0 spec is to digitally sign the Assertion (see https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf#page=17 - section 4.1.3.5). That is enough to tell if the SSO operation from an IdP should be trusted by SP that has federated with it.

    It is RECOMMENDED that the HTTP requests in this step be made over either SSL 3.0 [SSL3] or TLS 1.0
    [RFC2246] to maintain confidentiality and message integrity. The <Assertion> element(s) in the
    <Response> MUST be signed, if the HTTP POST binding is used, and MAY be signed if the HTTPArtifact binding is used.
    
    The service provider MUST process the <Response> message and any enclosed <Assertion>
    elements as described in [SAMLCore].
    

    Signing Response

    Signing the outer Response is optional. There are some security benefits to it, such as preventing Message Insertion or Modification...

    ...but in practice it's often omitted in lieu of relying on SSL/TLS.

    Possible combinations

    There are 8 (3x2) combinations.

    The SAMLTool.com website has an example for each.

    They list them in this order: (numbers, [NOTE]s and padding added for readability)

    1 000 An unsigned SAML Response with an [unencrypted]  unsigned  Assertion
    2 001 An unsigned SAML Response with a  [unencrypted]    signed  Assertion
    3 100 A    signed SAML Response with an [unencrypted]  unsigned  Assertion
    4 101 A    signed SAML Response with a  [unencrypted]    signed  Assertion
    5 010 An unsigned SAML Response with an    encrypted  [unsigned] Assertion
    6 011 An unsigned SAML Response with an    encrypted     signed  Assertion
    7 110 A    signed SAML Response with an    encrypted  [unsigned] Assertion
    8 111 A    signed SAML Response with an    encrypted     signed  Assertion
    

    https://www.samltool.com/generic_sso_res.php (Archived here.)

    FYI: You can not directly tell the difference between 5 and 6 or 7 and 8 just by inside the files. The structure is the same. You just see that the assertion is ENCRYPTED. But without the decryption key you can not look inside the <xenc:CipherValue> and say whether it's also SIGNED or not. (But in these examples the Encrypted+Signed `xenc:CipherValue are about 5500 characters while the just-encrypted are only around 3000 characters.)