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.
Related
I'm writing an app that I'm trying to integrate into a Shibboleth/SAML authentication provider. I'm the SP, I believe (I'm using github.com/crewjam/saml for the SAML code). I've gotten the code to work with https://samltest.id and one other Shibboleth implementation.
A third Shibboleth implementation does not work, however. The tech support for the non-working server has given me its IdP URL, which appears to contain similar XML as the other two IdP URLs. In addition, the tech support emailed me a file containing another certificate -- not included in the XML -- and asked me whether I was using it.
At this point, I'm a little confused as to what exactly I need to implement. Do I need to somehow include this emailed certificate manually in my code? Or, should I rely on the XML to provide the right information?
I'd appreciate any advice!
The answer to this question depends on your "non-working" IdP. A SAML entity uses public key cryptography to secure the data transmitted to trusted partners. Public keys are published in the form of X.509 certificates in metadata whereas the corresponding private keys are held securely by the entity. These keys are used for message-level signing and encryption, and to create secure back channels for transporting SAML messages over TLS.
IF the IdP metadata (the XML document) is correct, it should contain the IdP's public key. Ideally you should rely on the metadata and the public key in the metadata but Things Happen(tm) and the cert in metadata might not be what you want.
See this answer for a little more detail on that.
I'm integrating with a 3rd party and for the claims configuration, they recommended we create sAM-Account-Name to Name ID, and keep getting this error in the SAML response:
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Requester">
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy" />
</samlp:StatusCode>
</samlp:Status>
So I assumed I was not sending the correctly formatted NameID. In the SP's metatdata, they have this listed:
<NameIDFormat>
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
</NameIDFormat>
Rightly so, I assume I'm supposed to use the transient NameID format. However, that doesn't work either, and the vendor insists they expect our SAML response to use urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified as the Name ID format. From what I understand, that's default for ADFS.
As a test, I followed the steps here: https://blogs.msdn.microsoft.com/card/2010/02/17/name-identifiers-in-saml-assertions/ and was able to get a bogus NameID (transient) to pass to the vendor's site, where it then displayed back in the browser that the username was not valid, so at least I got something which makes me believe I'm on the right track and their authentication server is expecting transient while their application is not.
I would try the steps here, but I don't want to affect my whole claims provider: https://social.technet.microsoft.com/wiki/contents/articles/4038.ad-fs-2-0-how-to-request-a-specific-name-id-format-from-a-claims-provider-cp-during-saml-2-0-single-sign-on-sso.aspx
We're running Server 2012 R2 for our ADFS server. This isn't the first Relaying Party Trust we've configured, and our setup is working well with our other vendors. I however, am relatively new to managing ADFS, so I may have missed something simple.
Any thoughts or guidance would be appreciated.
If the claims mapping in ADFS for your relying party includes Active Directory samAccountName to SAML NameID, the "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" specified by the service provider's metadata doesn't really make a lot of sense as this value isn't transient.
As per the SAML v2.0 specification, the optional NameIDPolicy in the SAML authn request "specifies constraints on the name identifier to be used to represent the requested subject".
In practice, it's simpler to either not include a NameIDPolicy so it defaults to "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified" or explicitly use this value.
Given the above, the NameIDFormat in the service provider's metadata can be safely ignored and NameIDPolicy not included in the authn request.
The the SP can deny a claim based on its format, which is ultimately the issue. The solution then is the SP should either change their requirements, or one must send the claim in the required format.
In this case, the SP is requiring the claim to be transient, even though they verbally require unspecified (default). Verbal claim requirements don't count when dealing with systems!
To get ADFS configured with this SP, one simply needs to:
Create a transform rule, with the rule template: Send LDAP Attributes as Claims
LDAP attribute is SAM-Account-Name
Outgoing Claim Type is whatever you want it to be (custom text, not from the dropdown)
Create another transform rule with the rule template: Transform an Incoming Claim
The incoming claim type is whatever your Outgoing Claim Type was previous.
The Outgoing claim type is then Name ID with the format as Transient Identifier.
This will allow the sAM-Account-Name to be sent to the SP with a transient format, even though we know that attribute is by definition, not transient.
See screenshots:
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.
Should a SAML federation software accept the same SAML response as long as it is within the allowed SAML token lifetime?
In simpler terms: IDP (identify provider) issues a SAML response, then SP (service provider) accepts/processes it. Can the same unmodified SAML response be then re-used immediately after the first use? Given that the SAML issuance timestamp is within allowed range.
Security-wise it makes sense to restrict a SAML token (response) to only one use, so that even if it is stolen by a "man-in-the-middle" - it cannot be reused. But in order to implement that, the software needs to store some info about the SAML response somewhere: serial number, a hash of the whole thing?
Please provide some links with the explanations on that is possible and/or examples of implementation.
Thank you!
Alex.
The SAML 2.0 norm provides another way to prevent replay attacks that do not imply storing in database the ID of the assertion.
The SP sends a request with an ID="X" and stores this ID in session.
The IDP authenticates the user and sends back a Response with an ID="Y" AND a InResponseTo="X" (which is also normally present in the assertion in the SubjectConfirmationData).
The SP gets the Response and check that all the InResponseTo values match the one in session. If not, the SP rejects the response.
The SP clears the ID in session, thus making replay of the Response impossible. In the ideal case, the SP should clear the ID in session as soon as it receives the response.
This check really complicates the replay attack, as an attacker will also need to have the session cookie of the SP (and even in this case, it's already game over anyway...).
It's also good practice to sign the whole response.
Obviously this method is only valid in a SP-initiated scenario.
Does it make sense, security-wise? Sure. And in fact you can use the "xs:ID" portion of an assertion to assist you (my company's software does).
From Page 9 of CORE:
The xs:ID simple type is used to declare SAML identifiers for
assertions, requests, and responses. Values declared to be of type
xs:ID in this specification MUST satisfy the following properties in
addition to those imposed by the definition of the xs:ID type itself:
• Any party that assigns an identifier MUST ensure that there is
negligible probability that that party or any other party will
accidentally assign the same identifier to a different data object.
• Where a data object declares that it has a particular identifier,
there MUST be exactly one such declaration.
We snatch that ID from an assertion, and drop it into an array with the not-after time, and then throw it out after that time expires. This way the same assertion can't be replayed.
In other software (especially home-grown stuff), this is entirely managed with the Not-Before and Not-On-Or-After portion of the Audience Restriction. Since some software counts solely on these values, the suggested method is to set this period as short as is reasonable. In the perfect world, everyone is using time servers, and their clock skew isn't more than a couple of seconds. A minute prior, and a minute post issue time should be far more than sufficient. While there isn't as much "security" here, it can be "managed".
I am new to SAML. I want to know how to secure the SAML request and response communication between Service Provider and Identity Provider? I have seen an element digest in SAML response message examples. Can that be helpful to solve my doubt. How is that implemented?
Are you creating or validating signatures? Here are the (really) basic steps --
canonicalization of XML
create digest value, typically SHA1 (but could be SHA256 amongst others)
base64 encode it
SAML requires the XML Signature Syntax and Processing specification (http://www.w3.org/TR/xmldsig-core/) for signed messages. If you don't do this properly, you will have interop issues with other 3rd Party partners since they won't be able to validate your signed messages (resulting in invalid messages) or you will not be able to validate their messages.
If you don't understand the crypto in SAML, you're probably better off using a commercial product (like products from Ping Identity [Note:I do work for Ping]) to 1) speed up your deployment and more importantly 2) ensure that you are secure and compliant.