Validate assertion after request replay attack - itfoxtec-identity-saml2

I have tried to do a replay attack on my own integration of nemlog-in 3 authentication, but i'm having trouble figuring out how to implement protection against it. I have intercepted the request to my assertion endpoint, after login on the IdP, and then saved the SAML response for later use.
If i login again and replace the SAML response in my new assertion request with the old SAML response, then i'm still getting authenticated. I expected to get rejected, since it's old and have already been used. Do you have built in protection against replay attacks in your saml2 NuGet package or do i have to keep track of received SAML responses myself?

You need to enable replay validation DetectReplayedTokens (default disabled) https://github.com/ITfoxtec/ITfoxtec.Identity.Saml2/blob/master/src/ITfoxtec.Identity.Saml2/Configuration/Saml2Configuration.cs#L55
.NET Core / .NET 5
And set the TokenReplayCache / implement the ITokenReplayCache https://github.com/ITfoxtec/ITfoxtec.Identity.Saml2/blob/master/src/ITfoxtec.Identity.Saml2/Configuration/Saml2Configuration.cs#L48
.NET Framework
And set the TokenReplayCache / implement the IdentityModelCaches
https://github.com/ITfoxtec/ITfoxtec.Identity.Saml2/blob/master/src/ITfoxtec.Identity.Saml2/Configuration/Saml2Configuration.cs#L45
and set the TokenReplayCacheExpirationPeriod
https://github.com/ITfoxtec/ITfoxtec.Identity.Saml2/blob/master/src/ITfoxtec.Identity.Saml2/Configuration/Saml2Configuration.cs#L46

Related

Sustainsys.Saml2 SLO Logout RequestDenied status error

I need help in implementing Single Logout.I'm able to implement SSO service successfully.But SLO service is not working.
I got RequestDenied status code after performing logout on my OWIN based asp.net MVC application.
<saml2p:LogoutRequest
Destination="https://sap-client.accounts.ondemand.com/saml2/idp/slo/sap-client.accounts.ondemand.com"
ID="idb2d655f7174f465696a433c75a717b46" IssueInstant="2019-08-03T02:16:03Z" Version="2.0"
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2:Issuer>https://sp.domain.com/Saml2</saml2:Issuer>
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">xxx#xxx.com</saml2:NameID>
<saml2p:SessionIndex>S-SP-6aff8686-a642-4381-8ab3-0f18c6815ffe</saml2p:SessionIndex>
<LogoutResponse Destination="https://sp.domain.com/Saml2/Logout" ID="S0e6a2f99-2517-4326-a8ce-2ede2dfe1bfa" InResponseTo="idb2d655f7174f465696a433c75a717b46" IssueInstant="2019-08-03T02:16:04.933Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ns2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns4="http://www.w3.org/2001/04/xmlenc#" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#">
<ns2:Issuer>sap-client.accounts.ondemand.com</ns2:Issuer>
<Status>
<StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Requester">
<StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:RequestDenied" />
</StatusCode>
<StatusMessage>Identity Provider could not process the logout message received.</StatusMessage>
</Status>
Here is Owin log
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Error: 0 : Error in Saml2 for /Saml2/Logout
Sustainsys.Saml2.Exceptions.UnsuccessfulSamlOperationException: Idp returned status "Requester", indicating that the single logout failed. The local session has been successfully terminated.
at Sustainsys.Saml2.WebSso.LogoutCommand.HandleResponse(UnbindResult unbindResult, StoredRequestState storedRequestState, IOptions options, Uri returnUrl)
at Sustainsys.Saml2.WebSso.LogoutCommand.Run(HttpRequestData request, String returnPath, IOptions options)
at Sustainsys.Saml2.Owin.Saml2AuthenticationHandler.d__4.MoveNext()
ProcessId=14888
DateTime=2019-08-04T06:16:22.3060366Z
Thank you in advance.
The Idp returns an error. You should check the logs on the Idp to get more information on why.
It might also be worth using SAML dev tools for Chrome to check the actual messages, there might be more status codes embedded in the response.
One reason that this might occur is if you have a long lived session in your application that extends beyond the life time of the Idp session. With owin based applications where the external login session is typically swapped to an application login session this might happen - the session life time limit is lost in the swap done in ExternalLoginCallback.

Switch SAML binding from Post to Redirect

As an SP, we've opted for the POST binding option - it seemed to be the advised approach. SAML is now set up and working with the IDP. We would now like to change to Redirect as it is better handled in Ajax calls after timeout.
My question is whether we can switch from POST to Redirect without incurring a setup change on the IDP side. Seeing as both bindings are just using the UserAgent (browser) as a transport anyway, I figured it may be possible. But the binding is defined in the AssertionConsumerService in the metadata which indicates that IDP would need to be informed and have its configuration changed.
Sending a SAML Response (which is what is sent to an Assertion Consumer Service endpoint) via Redirect is not supported by the SAML spec since responses easily get too large to send as a query parameter. See line 420 in the SAML Web SSO Profile spec https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf
Identity Provider issues to Service Provider In step 5, the identity provider issues a message to be delivered by
the user agent to the service provider. Either the HTTP POST, or HTTP
Artifact binding can be used to transfer the message to the service
provider through the user agent. The message may indicate an error, or
will include (at least) an authentication assertion. The HTTP Redirect
binding MUST NOT be used, as the response will typically exceed the
URL length permitted by most user agents.
You can switch to Artifact, though SP metadata will need to updated on the IDP to relay the changed endpoint.

SAML consumer URL

We are implementing SAML integration and I am the service provider and my identity provider is asking me to send "SAML Consumer URL" and "RelayState"
I would need help to understand what is SAML consumer URL & RelayState and how do I get/generate it for my application.
Thank you for your time and help!
TLDR, AssertionConsumerUrl (ACS) endpoint is SAML protocol endpoint, RelayState is like cross-domain cookie, used to coordinate messages and actions of IdPs and SPs.
In 5.1.Web Browser SSO Profile of SAML 2.0 Technical Review, it will give you a general understanding of how the flow goes.
Down to the SSO implementation, for example Shibboleth, this FlowAndConfig doc details the SSO flow pretty well.
In 2. SP Determines IdP and Issues Authentication Request:
Cookie Set by SP
During this step, the SP will preserve the original
resource requested by the browser using a "relay state" mechanism,
which is configured by a relayState property on the <SessionInitiator>
element. The default mechanism does not rely on a cookie any longer,
but many systems do, and send a state management cookie containing the
resource URL to the client along with the request prepared for the IdP
or DS/WAYF.
In 5. Back to the SP:
The browser delivers the response from the IdP to an Assertion Consumer Service endpoint at the SP.
relay state info returned from IdP to SP
Cookie Read by SP
The "relay state" information returned by the IdP, if any, will have
been created by the SP and if using a cookie, will point to a
specially named cookie that should accompany the authentication
response supplied to the ACS endpoint in this step. This is the cookie
set in Step 2 above. If this cookie is missing (or if no relay state
exists at all), the associated application's homeURL property is
substituted as a fall back.
Also, Shibboleth has some wiki for those two terms as well.
AssertionConsumerService concept
RelayState concept
Hope it helps!

Is it possible to just parse the SAML assertion response without authenticating with IDP?

I'm facing a problem with validating SAML response where in, its giving digest mismatch. Tried checking it with the certificate's digest value and its showed a different value. I think there is a problem with the certificate or the SAML response but, I'm also wondering whether not having an authentication at the SP level is also a cause for concern since, the client does not want a response back on the IDP, contrary to what the standard setup for SAML dictates. I realize there shouldn't be a setup of this sort due to obvious security concerns but, this was the setup they have requested...
If the SAML assertion is not signed properly, this is a security concern and you should not trust it. By trusting it without validating the digest, you would open your self up to anyone submitting SAML to your ACS URL and being authenticated.

Spring Security SAML assertion expiry with Application Session Expiry

I'm getting confused with the SAML assertion expiry vs Application session expiry.
In simple words, when we have an application deployed in a container, there is a session created. This session expiry can be controlled with the below entry in web.xml
<session-config>
<session-timeout>60</session-timeout>
</session-config>
Moving on, when I have Spring Security with SAML extension, obviously the same session concept applies. (I'm deploying the application in WildFly 8.2, if that matters)
Further, when the application session expires, the logout behaviour seems to be equivalent to Local Logout concept.
So far so good. Now lets say that the SAML assertion is good for 2 hours and the user has been actively working for 2 hours. What should happen to the subsequent request then? Should it re-login to the IDP? But, wouldnt that be inconvenient to the user? If the application redirects to IDP for logging in again after 2 hours of assertion expiry, How should AJAX requests be handled?
This is in reference to the question here
Spring SAML issues an ExpiringUsernameAuthenticationToken for authenticated users. The token starts returning false in its isAuthenticated() method once the SAML Assertion used to authenticate the user reaches its sessionNotOnOrAfter time.
This behavior can be disabled by overriding SAMLAuthenticationProvider and changing method getExpirationDate(credential), which returns time when the Assertion expires, or null in case it never does. Application will then fully rely on session expiration configured in the container.
Once the ExpiringUsernameAuthenticationToken expires, Spring Security will pass the current token to the AuthenticationManager (configured in securityContext.xml under <security:authentication-manager>).
You can affect what happens next, by adding your own AuthenticationProvider able to handle the ExpiringUsernameAuthenticationToken. Otherwise system fails with ProviderNotFoundException or some other AuthenticationException like BadCredentialsException (in case you're using username/password authentication at the same time).
The exception is subsequently handled by ExceptionTranslationFilter, which start new authentication process by invoking the configured authentication EntryPoint - e.g. SAMLEntryPoint which either starts authentication with default IDP or displays IDP selection page. The process will also essentially perform local logout, as you say.
System by default behaves the same for all HTTP calls - AJAX or not. You can define different behavior by splitting your API and normal URLs into separate <security:http> elements and use different EntryPoints (interface AuthenticationEntryPoint) for each. For example Http403ForbiddenEntryPoint might be suitable for your AJAX calls.

Resources