We are trying to setup a custom SAML integration with the Cisco WebEx. However WebEx SP keeps complaining about the "Invalid digital signature" after the SAML Response is sent to WebEx.
We have already inspected the SAML Response, Signing Cert, and the Fiddler trace of the SAML transaction. Nothing seems out of ordinary. We have done this for several other services and have not run into any issues.
Is there a good tool that can help us debug as to why WebEx is thinking the Digital Signature is invalid?
There are a few reasons why a digital signature might be seen as invalid.
Altered Document:
Ensure that the document you are signing is not in any way altered after it is signed. Even the addition of a whitespace character will invalidate the signature.
Character Encoding:
If your document contains unicode charaters, ensure that you have the correct encoding specified. Most SAML documents are expected to be encoded in UTF8 like so: <?xml version="1.0" encoding="utf-8"?>
Wrong Element Signed: A SAML document containing an Assertion is usually expected to have a signature on the Assertion itself, and not necessarily on the entire document.
Incorrect Certificate: Ensure that the certificate you've given the authority is a match with the key you are signing. Some implementations will have you include the certificate in the document, where others might require you to predefine the certificate. If the one in your document does not match the one they have on file, the signature will not be seen as valid. Are you signing with an SSL certificate? Did you recently update it?
Ultimately you should test the document yourself. Many SAML libraries will have a mechanism for validating a signature. Does yours appear valid to your library? Failing that, you can use something like xmlsec1 to manually validate your document with your certificate. This is likely what your library is using to encrypt, and likely what the authority is using to validate.
Using XMLSec:
Given a certificate called cert.pem and a SAML Response XML document called doc.xml you would validate it like so:
$ xmlsec1 --verify --pubkey-cert-pem cert.pem --id-attr:ID Response doc.xml
OK
SignedInfo References (ok/all): 1/1
You may need to alter the --id-attr value to match the ID attribute of your document. You are looking for output similar to the above to inform you that your document's signature is valid with the provided certificate.
Check that you're signing the Assertion element, not the toplevel Response element.
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.
When building a Conversational Action with the new Actions SDK or Action Builder, you can define a webhook to handle business logic. This webhook then receives fulfillment requests with the following headers, among others:
Google-Actions-API-Version: "3"
Google-Assistant-Signature: "eyJhbGciOiJSUzI1NiIsImtpZC..."
How should that signature be verified? It's a JWT claim, but the key ID with which it was signed does not exist in the GCP account linked with the Action, and is not mentioned in the new Actions SDK documentation or in the Node.js fulfillment library documentation.
The signature is a JSON Web Token, which is an encoded way of transmitting some assertions that have been signed in a verifiable way. There are libraries that will both decode and verify JWTs. The general steps (some of which you can cache or shortcut) are:
Decode the header to get the kid (key id) and the payload to get the iss (issuer) fields. You'll also want the nbf (not before) and exp (expiration) fields to verify this was set recently and the aud field to verify that it matches your Google Cloud project ID.
Based on the issuer, access the well known openid configuration. Since the issuer is "https://accounts.google.com" you can access this at "https://accounts.google.com/.well-known/openid-configuration"
From the configuration document, you want the jwks_uri field, which is the URL to get the current JWT certificates. For Google, this is probably "https://www.googleapis.com/oauth2/v3/certs"
The certificate document should contain an array of keys. You want a key with the kid that matches the kid from the JWT. Note that these keys change frequently, but as long as you're within the window of the nbf and exp fields from the signature header, the key should exist in the certificate document.
With all this, you can then verify the signature portion of the JWT.
I am attempting to use https://www.samltool.com/validate_authn_req.php to validate a saml request. I have fed it the samlrequest, the signature, relaystate, base64 encoded token signing cert from SP and sigalg. Yet it complains of idp_cert_or_fingerprint_not_found_and_required. I don't know why it needs the private key of the IDP given that the request has nothing encrypted within it.
I am hoping Onelogin folk like #smartin will see this and have a suggestion. Else, does anyone else have any tips on another way I can confirm if the signature received with a SAML authnrequest is valid?
Quick question,
Could there be any explanation for the fact that the IdP sends a certificate that is old and doesn't match the certificate that the SP expects, but SSO still works?
Could it be that the public keys somewhere else still match?
I have seen certificates where the public key doesn't change but the expiry date, serial number etc do change. This isn't common though.
The more likely scenarios are:
(i) the IdP is using the certificate expected by the SP,
(ii) the SP is using the embedded certificate,
(iii) the SP isn't verifying the signature.
If you take a look at the received SAML response it normally includes the base-64 encoded certificate embedded in the XML signature.
You can check this against the certificate you are expecting.
I'm working with a customer who has built a home-grown engine to generate SAML assertions. We are using ForumSentry to validate the assertion, but the digest is failing to validate. We already have a dozen other customers sending us SAML assertions, for web SSO, perfectly well, and I'm sure ForumSys have many 100's of customers for ForumSentry working perfectly well too.
I've spent many hours trying to understand exactly what the digest is made of and trying to find samples of XML which goes into the digest algorithm. I've failed and I would appreciate some help please.
It seems to me that the only data signed is the reference URI, and not all other the "parameters" of the assertion, such as the subject, issuer, etc. Is this correct / what don't I understand? What is the background to this? If correct, how is the other data protected from tampering?
Is there an assumption that Web SSO must be over HTTPS to protect the integrity of the entire assertion?
What data exactly forms the data that is signed? Could someone post an example please, both pre and post canonicalization of data that is signed.
Any other background info would be great.
SAML uses XML DSig for signing. When a SAML entity (an assertion, an entire Response, metadata etc...) is signed it is done by using specific algorithms in the XML Dsig suite.
The reference of the signature must point to the ID of the signed entity. For a signed assertion that is the ID attribute of the <assertion> node.
The canonicalization algorithm used must be Exclusive Canonicalization. This is nothing that affects the actual XML contents, it is an instruction to the XML parser used by the crypto library that makes sure that whitespace differences etc. won't affect the validity of the signed data.
XML DSig works in two steps:
First a hash is calculated for each reference in the signature. For SAML signing there should only be one reference to the ID attribute of the enclosing entity.
Then a cryptographic signature is calculated across the XML containing the hashes.
This means that a single signature can be used to verify the integrity of several pieces of XML, but in SAML that functionality is not used.
With each signature containing exactly one reference to the ID attribute of the signed entity, the entire entity is protected by the signature.
I'd suggest that you read the SAML core spec section 5.4 if you need more details on how the XML signature works with SAML.