Monday, July 14, 2014

[Dissecting SAML Spec] Validation of Assertion Consumer Service URL

Assertion Consumer Service URL is the endpoint at Service Provider side to which the SAML Assertions will be sent by the SAML IdP. When sending a SAML Authentication Request, the SP can specify the ACS URL that he prefers.

So, how should a SAML IdP treat/validate the ACS URL that is coming inside a AuthnRequest from an SP? Let's check what SAML specs have to say...

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
        <samlp:Issuer xmlns:samlp="urn:oasis:names:tc:SAML:2.0:assertion"></samlp:Issuer>
        <saml2p:NameIDPolicy xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
        <saml2p:RequestedAuthnContext xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>

According to SAMLMeta spec section 2.4.4, it is mandatory that at least one ACS URL of a SP is registered at the IdP prior to communication between the parties:
<AssertionConsumerService> [One or More]
One or more elements that describe indexed endpoints that support the profiles of the Authentication Request protocol defined in [SAMLProf]. All service providers support at least one such endpoint, by definition."
So, does that mean SP should only send that registered ACS URL in the request? SAMLProf has this to say in section
The location of the assertion consumer service MAY be determined using metadata (as in [SAMLMeta]). The identity provider MUST have some means to establish that this location is in fact controlled by the service provider. A service provider MAY indicate the SAML binding and the specific assertion consumer service to use in its <AuthnRequest> and the identity provider MUST honor them if it can.
Section also states:
Note that if the <AuthnRequest> is not authenticated and/or integrity protected, the information in it MUST NOT be trusted except as advisory. Whether the request is signed or not, the identity provider MUST ensure that any <AssertionConsumerServiceUrl> or <AssertionConsumerServiceIndex> elements in the request are verified as belonging to the service provider to whom the response will be sent. Failure to do so can result in a man-in-the-middle attack.
So we can come to the following conclusions:

1. If no AssertionConsumerServiceUrl is given in the <AuthnRequest> IdP must send the response to one of the registered ACS URLs of the SP.

2. If the AssertionConsumerServiceUrl in <AuthnRequest> matches with one of the registered URLs, send the response to it.

3. If the AssertionConsumerServiceUrl in <AuthnRequest> does not match with any of the registered ACS URLs and if the request is signed (which removes the possibility of man-in-the-middle attack), then send the response to the ACS URL in the request only if the signature is valid.

4. Else, reject the <AuthnRequest>


DarRay said...

Does that means IdP should be able to register multiple ACS URLs?

dulanja said...

Yes, and one should be selected as the default

Anonymous said...

Hi Dulanja,

Is there any mechanism to get the error message in rejected request to the service provider ? If its not available,

Is there any possible scenario by redirecting response with an error message to /commonauth endpoint and /samlsso endpoint ?