Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit IdP signing key feedback #1791

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

pablothedude
Copy link
Contributor

An explicit IdP signing key check is added for easier debugging.

The ease of debugging should outweigh the drawbacks of moving the responsibility of the SAML2 library also to EB and the performance penalties for doing this twice.
#1328

@pablothedude pablothedude force-pushed the feature/add-expicit-signing-key-check branch from bdaf2a0 to cefd336 Compare January 27, 2025 15:44
An explicit IdP signing key check is added for easier debugging.

The ease of debugging should outweigh the drawbacks of moving the
responsibility of the SAML2 library also to EB and the performance
penalties for doing this twice.
#1328
@pablothedude pablothedude force-pushed the feature/add-expicit-signing-key-check branch from cefd336 to d6f3eac Compare January 28, 2025 09:35

$validKey = false;
foreach ($metadata->certificates as $metaDataCertificate) {
if ($metaDataCertificate->toCertData() === $sspResponse->getCertificates()[0]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This always checks only the first certificate. Is it certain that there never will be > 1 certificate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Thijs, that was something I was wondering too. Because it seemed to me that a response would only be signed by one key. And therefore I wanted to ask @baszoetekouw if and when this would happen. But you beat me to it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XML signature standard does not limit the number of KeyInfo or X509Data elements in a Signature. So there could be any number, including none according to XML Signature.

The purpose of a KeyInfo is to specify what key was used to sign, an thus what key must be used to verify the signature: "KeyInfo indicates the key to be used to validate the signature." In my opinion it does not make sense to have keyInfo pointing to multiple keys.

This is how the Stepup SAML Bundle handles this: https://github.com/OpenConext/Stepup-saml-bundle/blob/main/src/SigningSignatureVerifier.php#L40

I think it is unlikely that an IdP or SP would be putting more than one KeyInfo with an X509Data element, or more than X509Data elements in a KeyInfo in a Signature. I've never seen this happen, but I cannot rule out that someone out there is doing this.

Copy link
Member

@baszoetekouw baszoetekouw Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmeulen your link is broken, unfortunately? Were you referring to https://github.com/OpenConext/Stepup-saml-bundle/blob/main/src/Signing/SignatureVerifier.php ? The flow there is simpler than what we propose here. Afaics, Stepup simply tries to verify the signature with all trusted keys; it doesn't seem to differentiate between the wrong key being specified in the assertion (i.e., unknown key in <KeyInfo>) or any other type of signature validation failing.

Anyway, I have been trying to track down in the SAML2 code where the signing certificates are added, but I'm having trouble finding it. It's not clear for example which <ds:Signature>s exactly are considered.
The SAML spec at least says that multiple elements in the Response can be signed, and that the signature then applies to all descendent element, so that suggests that it considers (for example) both the Response signature and the Assertion signature.

So it's probably best to iterate over all certificates returned by $sspResponse->getCertificates(). The question remains of course, of whether to raise an error if all of them are unknown, or if any of them is unknown. The latter sounds safer (and might defend against wrapping attacks even), but might cause failures for SAML Reponses from obscure IdPs.
@thijskh @pmeulen what do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should err of the safe side, and check all of the signatures. If even one of them is unknown, reject the message.
Any normal message should pass this test; an IdP that does something strange like signing a message with two different keys should be investigated anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@pmeulen pmeulen Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a fan of being strict.

  • Only allow Signatures element in normal locations (on Assertion, on SAMLRequest)
  • Only one SignatureValue per Signature
  • Only one KeyInfo of the X509Data per SignatureValue

If we're think this breaks things, we make these checks log a warning at first, and run this in production for a wile. Then we investigate any warnings that we see, and decide what to do.

But I don't expect this to be an issue. See e.g. the checks that the (new) SSP library does:

https://github.com/simplesamlphp/xml-security/blob/feb95e14e9c9941681ac6d2fc5880691b61afff7/src/XML/ds/Signature.php#L114-L148

Also earlier drafts of the XML-DSIG spec had these restrictions, this was later changed to unrestricted.

@pablothedude pablothedude marked this pull request as draft January 28, 2025 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Explicit check if signing certificate of SAML response is known
4 participants