Skip to content

Commit

Permalink
Resolve XML-encoded carriage returns during signature validation (#576)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhassan1 committed Apr 5, 2021
1 parent 0798e4d commit 5618b65
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/node-saml/saml.ts
Expand Up @@ -738,6 +738,8 @@ class SAML {
if (totalReferencedNodes.length > 1) {
return false;
}
// normalize XML to replace XML-encoded carriage returns with actual carriage returns
fullXml = this.normalizeXml(fullXml);
fullXml = this.normalizeNewlines(fullXml);
return sig.checkSignature(fullXml);
}
Expand Down Expand Up @@ -1465,6 +1467,12 @@ class SAML {
// https://github.com/node-saml/passport-saml/issues/431#issuecomment-718132752
return xml.replace(/\r\n?/g, "\n");
}

normalizeXml(xml: string): string {
// we can use this utility to parse and re-stringify XML
// `DOMParser` will take care of normalization tasks, like replacing XML-encoded carriage returns with actual carriage returns
return new xmldom.DOMParser({}).parseFromString(xml).toString();
}
}

export { SAML };
22 changes: 22 additions & 0 deletions test/node-saml/test-signatures.spec.ts
Expand Up @@ -279,4 +279,26 @@ describe("Signatures", function () {
await testOneResponseBody(body, false, 1);
});
});

describe("Signature on saml:Response with XML-encoded carriage returns", () => {
const samlResponseXml = fs
.readFileSync(
__dirname + "/../static/signatures/valid/response.root-unsigned.assertion-signed.xml"
)
.toString();
const makeBody = (str: string) => ({ SAMLResponse: Buffer.from(str).toString("base64") });

const insertChars = (str: string, where: string, chars: string) =>
str.replace(new RegExp(`(<ds:${where}>)(.{10})(.{10})`), `$1$2${chars}$3`);

it("SignatureValue with &#13;", async () => {
const body = makeBody(insertChars(samlResponseXml, "SignatureValue", "&#13;"));
await testOneResponseBody(body, false, 2);
});

it("SignatureValue with &#xd;", async () => {
const body = makeBody(insertChars(samlResponseXml, "SignatureValue", "&#xd;"));
await testOneResponseBody(body, false, 2);
});
});
});

0 comments on commit 5618b65

Please sign in to comment.