Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
BindingNamespace,
ParserType,
wording,
MessageSignatureOrder,
StatusCode
} from './urn';

Expand Down Expand Up @@ -225,6 +224,7 @@ async function postFlow(options): Promise<FlowResult> {
// Encrypted Assertion, the assertion is signed
const result = await libsaml.decryptAssertion(self, samlContent);
const decryptedDoc = result[0];
samlContent = decryptedDoc;
const [decryptedDocVerified, verifiedDecryptedAssertion] = libsaml.verifySignature(decryptedDoc, verificationOptions);
if (decryptedDocVerified) {
// extractor depends on signed content
Expand Down
6 changes: 2 additions & 4 deletions src/libsaml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,6 @@ const libSaml = () => {
const { dom } = getContext();
const doc = dom.parseFromString(xml);

const docParser = new DOMParser();
// In order to avoid the wrapping attack, we have changed to use absolute xpath instead of naively fetching the signature element
// message signature (logout response / saml response)
const messageSignatureXpath = "/*[contains(local-name(), 'Response') or contains(local-name(), 'Request')]/*[local-name(.)='Signature']";
Expand Down Expand Up @@ -455,8 +454,7 @@ const libSaml = () => {
}

sig.loadSignature(signatureNode);

verified = sig.checkSignature(doc.toString());
verified = sig.checkSignature(xml);

// immediately throw error when any one of the signature is failed to get verified
if (!verified) {
Expand All @@ -468,7 +466,7 @@ const libSaml = () => {
throw new Error('NO_SIGNATURE_REFERENCES')
}
const signedVerifiedXML = sig.getSignedReferences()[0];
const rootNode = docParser.parseFromString(signedVerifiedXML, 'text/xml').documentElement;
const rootNode = dom.parseFromString(signedVerifiedXML, 'text/xml').documentElement;
// process the verified signature:
// case 1, rootSignedDoc is a response:
if (rootNode.localName === 'Response') {
Expand Down
3 changes: 3 additions & 0 deletions test/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ test('send response with signed assertion and parse it', async () => {
expect(typeof id).toBe('string');
expect(samlContent.startsWith('<samlp:Response')).toBe(true);
expect(samlContent.endsWith('/samlp:Response>')).toBe(true);
expect(samlContent).toContain('>[email protected]</saml:NameID>')
expect(extract.nameID).toBe('[email protected]');
expect(extract.response.inResponseTo).toBe('request_id');
});
Expand Down Expand Up @@ -930,6 +931,7 @@ test('send login response with encrypted non-signed assertion and parse it', asy
expect(typeof id).toBe('string');
expect(samlContent.startsWith('<samlp:Response')).toBe(true);
expect(samlContent.endsWith('/samlp:Response>')).toBe(true);
expect(samlContent).toContain('>[email protected]</saml:NameID>')
expect(extract.nameID).toBe('[email protected]');
expect(extract.response.inResponseTo).toBe('request_id');
});
Expand Down Expand Up @@ -1102,6 +1104,7 @@ test('send login response with encrypted non-signed assertion with EncryptThenSi
expect(typeof id).toBe('string');
expect(samlContent.startsWith('<samlp:Response')).toBe(true);
expect(samlContent.endsWith('/samlp:Response>')).toBe(true);
expect(samlContent).toContain('>[email protected]</saml:NameID>')
expect(extract.nameID).toBe('[email protected]');
});

Expand Down