Skip to content

[BUG] When validating the SAML Response, it is assumed that the SAML Response ID attribute is the same as the SAML Assertion ID attribute #211

@ghost

Description

Hello,

I'm using Auth0 as the Identity Provider for my project. When Auth0 sends my app a SAML Response, the ID attribute of the samlp:Response element doesn't match the ID saml:Assertion element.

e.g.

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_05c1cd292f39027f463a" Version="2.0" IssueInstant="2022-11-10T21:53:21.890Z" Destination="https://localhost:8446/saml/callback">
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
        Auth0
    </saml:Issuer>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="_FSCsC9u7rraXQLZ8UoU9AxBHbbBxApnd" IssueInstant="2022-11-10T21:53:21.827Z">
        <saml:Issuer>
            Auth0
        </saml:Issuer>
        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
                ...
            </SignedInfo>
            <SignatureValue>
                ...
            </SignatureValue>
            <KeyInfo>
                <X509Data>
                    <X509Certificate>
                       ... 
                    </X509Certificate>
                </X509Data>
            </KeyInfo>
        </Signature>
    </saml:Assertion>
</samlp:Response>

I'm getting an error Invalid document signature when calling passport.authenticate().

I've stepped through the code and can see that you assume these IDs are the same.

saml.ts - line 690

let validSignature = false;
if (validateSignature(xml, doc.documentElement, certs)) {
  validSignature = true;
}

if (this.options.wantAuthnResponseSigned === true && validSignature === false) {
  throw new Error("Invalid document signature");
}

The error is being thrown because validSignature is false.

Looking at the validateSignature() method, the XPath is looking for a descendant (i.e. the Assertion element) with a matching ID to the root element (i.e. the SAML Response element).

xml.js - line 82

const xpathSigQuery =
  ".//*[" +
  "local-name(.)='Signature' and " +
  "namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#' and " +
  "descendant::*[local-name(.)='Reference' and @URI='#" +
  currentNode.getAttribute("ID") +
  "']" +
  "]";
const signatures = xpath.selectElements(currentNode, xpathSigQuery);
// This function is expecting to validate exactly one signature, so if we find more or fewer
//   than that, reject.
if (signatures.length !== 1) {
  return false;
}

Please could you amend your XPath so that it doesn't make this assumption?

Thanks,

Ben

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions