So I am implementing SSO over SAML2.0 for our application. We are using saml2-js on our side and we are doing SP initiated SSO.
The implementation is ready and it is working however there are a few parts I struggle wrapping my head around.
saml2-js requires you to provide a private-key and a certificate on the ServiceProvider instance -> https://www.npmjs.com/package/saml2-js#serviceprovideroptions I don't understand what these are used for and saml2-js don't provide any meaningful description about them. I tried to find out by understanding from a SAML point of view but I still don't know.
As an IdP, Okta is the target and after setting up SAML in Okta, Okta provides it's certificate. Now I understand that part because Okta will sign the Response and on our side, the SP uses that certificate to ensure that the Assertion came from a/the trusted party. But how does Okta make sure that the request came from a trusted party? I thought the certificate saml2-js requires from us will be used for that, but as it turned out this assumption was false because Okta doesn't get our certificate in any ways
When setting up SAML in Okta (okta guide) in point 6 they require you to fill the Audience URI which by default is the SP entity_id. But this can be an arbitrary value right? What is this used for and why is this mandatory?
The service provider requires a private key if it's signing SAML messages or decrypting SAML assertions. If neither is the case, a private key shouldn't be required.
I don't believe Okta requires the SAML authn request to be signed. This isn't unusual. If the SAML authn request isn't signed, the IDP can't be sure who sent the message but this normally wouldn't present any security issues. If you click the Show Advanced Settings link in the Okta configuration you get the option of supplying your certificate. However, this is only required for signing the logout messages.
The audience URI identifies the intended recipient of the SAML response which should be the SP. It's part of the SAML protocol and as such you would expect the SP to check its value against the SP's entity ID. If you take a look at the SAML specification it talks about its purpose as helping to uphold warranty exclusions in a court of law. You can draw your own conclusions as to how useful this is.
Related
Integrating one of my application with with SAML 2.0 single sign on. Using Okta provider for this. I came to the point where I receive base64 encoded "SAML response token" after successful authetication in okta and redirected back to my application. Within this token I see all the user details I need but here comes my question. Do I need to verify that response any futher or shall I just trust what I receice? Considering this token also contains signarure?
My idea for security would be to reach Okta again and verify if this was really issued by Okta. Not sure if this is even possible.
Using NodeJS for verification.
If by SAML response token you mean the samlp:Response issued according to the Web Browser Passsive SSO profile then then response contains an assertion and the assertion is signed by the Identity Provider (additionally, the whole response can also be signed).
There's a critical security requirement to always validate the response signature. This is mentioned in the SAML specs, section 4.1.4.3
The reason for this is as follows: in the Web Browser SSO Profile the token is returned by the Identity Provider in a web page that contains a simple form with SAMLResponse and RelayState fields and a bit of code that just autoPOSTs this form to your app. Technically, this means that for a short time the token is controlled by the user's web browser and this is where the token can be altered (or forged).
Thus, the protocol security heavily relies on the token's integrity which is achieved with the crypto signature - it's just a plain old XMLDSig signature applied to the SAML.
Your goal, as a token receiver is not only to validate the signature but also check the signature's certificate and compare it to the certificate you expect from the trusted provider (or a list of certificates of trusted providers).
Skipping this step makes your application vulnerable:
skipping the verification means users can alter the token (add/create/delete) claims to the assertion, the signature verification would fail but you skip it
skipping certificate matching against known certificate means users can forge their own assertions, sign it using a dummy certificate and present to your application. The signature verification step would succeed but you won't be aware that a dummy certificate was used to sign the assertion
If you don't want to do the proper token validation on a backend (don't blame you, it's a pain), then switch to OIDC. That's a better fit for authentication and authorization for the frontend.
If, however, the SAML response is sent to and handled by a backend, and some other token is being forwarded to your application, then you should evaluate what the requirement for the validation of that token is.
What isn't clear in your question is where in the user flow we're talking about, hence the number of comments on my answer.
SAML specification says next "The message MUST be signed if the HTTP POST or Redirect binding is used." and the same for LogoutResponse. But when I look for settings in different identity providers(onelogin, auth0, duo, Azure AD) I see that they doesn't require certificate from service providers for single logout(I find only one exception and it's okta).
Probably I don't understand conception or miss something and ask you community of stackowerflow to help me with this situation.
Your understanding is correct. The SAML specifications states SAML logout messages must be signed. However, not all SAML providers support SAML logout and, of those that do, not all support signing the SAML logout messages. If a logout message isn't signed this means a 3rd party could cause logout to occur. This would be a nuisance but I'm not sure if it's a security risk. If you're looking for maximum interoperability I recommend the signing of SAML logout messages to be configurable so you can vary the behavior depending on the partner provider.
I'm a Service Provider (SP) who wants to support multiple Identity Providers (IdP) via Web SSO profile.
I'm struggling to understand how should I negotiate SAML features (e.g. signing/not signing AuthnRequests) with Identity Provider admins.
Here's my current understanding:
I create a single sp-metadata.xml which I expose to all IdPs who want to integrate with me.
To integrate with me, IdP admins upload their idp-metadata.xml via my web interface. I validate it against my sp-metadata.xml. If their metadata features don't match with my metadata features, I show them a detailed error on upload so they can change their setup.
Questions:
Is this a valid and common approach?
How do I write SP metadata to support all or most IdPs out-of-the-box? For example, should I put "AuthnRequestsSigned = false" or "AuthnRequestsSigned = true"? It seems that Web SSO Profile does not give strict guidance on this.
About 2: You can not really validate the IdP meta data against your SP meta data. Most IdP's do not tell if they accept a digitally signed SAML AuthnRequest. They also typically do not tell which signature algorithm or keysizes they support.
Some IdP implementation do not even create SAML meta data schema compliant meta data files.
If you care about security, then you should digitally sign the SAML AuthnRequest and either ask the IdP to ignore the signature in case your SP sends it.
Also note that there some update to the spec for some time ... see the new processing rules.
Alternative: During upload ask (checkbox/radio button) if they can handle a digitally signed SAML AuthnRequest and which signature algorithm has to be used.
I.e. Microsoft ADFS and Azure AD bail out with an non-descriptive SAML error response if they can not handle the SAML AuthnRequest.
I am trying to understand the SAML 2 protocol and in that process got a little bit lost with the signature and certificate business.
Basically, I am not clear of when each of the certs are used.
Service Provider Meta Data and Identity Provider Metadata - do we need to generate certificates/keys as a part of the SP and IDP metadata? If so how/when will these certs be used?
HOK token also needs a certificate - when does that come into picture? Does the principal's certificate/public key needs to be exported to the IDP also along withe SP's certificate?
When using bearer tokens (they do not have any certs associated with the principal) is the SAML response/assertion still signed? Is it different from the ds:keyInfo in the SAML response in this case?
Thanks a bunch for the help!!
1.
Certificates in SP and IDP metadata are typically used for two purposes digital signing and digital encryption. Attribute "usage" on metadata makes the discrimination. Certificates are typically included in the metadata, but they could also be ommited and provided out-of-band (e.g. by direct configuration in IDP and SP, if supported). These keys identify the SP and IDP machines, they have nothing to do with the users.
When SP sends a SAML message towards IDP the message can be digitally signed using SP's private key (whose public key + certificate is included in the SP metadata and available to IDP), IDP is able to verify the SP's signature using the SP's public key.
When SP wants to encrypt part of the SAML data (whole message, assertion, name ID, attribute, ...) it uses public key declared in the IDP's metadata, IDP then decrypts the data using its private key.
Sometimes metadata can contain multiple signing or encryption keys, e.g. in case of certificate rollover before expiration.
2.
Bearer mechanisms are used to make sure that the entity (e.g. web browser) who is presenting a SAML message is allowed to do so. In SAML WebSSO AuthnResponse message gets issued by the IDP, but is delivered to the SP by the browser. HoK SubjectConfiguration tells that we are identifying the presenter by making sure that it can prove posession of a private key whose public key/certificate is included in the SubjectConfirmation element. This is typically done by usage of SSL/TLS Client Authentication (i.e. user installs private key in browser and uses it to authenticate toward SAML service when opening the HTTPS scheme with SSL/TLS).
So here we are dealing with keys issued directly to users, not to SP/IDP services. Whether or not you need to import user's certificate(s) to the IDP or not is IDP-implementation specific.
3.
Yes, the messages will still be signed (when configured to be) and KeyInfo in the SAML response will be the same in both cases.
Cheers,
Vladimir Schafer
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?
The only requirement for the IdP following the SAML 2.0 spec is to digitally sign the Assertion (see http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf - 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.
Signing the outer Response is optional. There are some security benefits to it, such as preventing Message Insertion or Modification (see sections 6.1.3/6.1.5 in http://docs.oasis-open.org/security/saml/v2.0/saml-sec-consider-2.0-os.pdf) - but in practice it's often omitted in lieu of relying on SSL/TLS.
The whole point of signing the response is to prove that they actually do come from the issuer. Otherwise a "man in the middle" could change the attributes e.g. to give themselves access to an application.
ADFS v2.0 using SAML by default signs all response tokens. There's no way to turn this off.