From e76c8142fd68c7f3d69a21f61421dcb84364ffcd Mon Sep 17 00:00:00 2001 From: Andrew Maillet Date: Mon, 13 Nov 2017 10:51:59 -0500 Subject: [PATCH 01/11] accept saml response with xml sig namespace at the root level the xml dsig namespace can be specified at the root of the SAML response instead of on each Signature element. The canonincalized xml for the signature element requires that the namespace declaration be present on the siganture element. --- lib/saml2.coffee | 3 +- ...d_response_twice_signed_dsig_ns_at_top.xml | 39 +++++++++++++++++++ test/saml2.coffee | 4 ++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 test/data/good_response_twice_signed_dsig_ns_at_top.xml diff --git a/lib/saml2.coffee b/lib/saml2.coffee index fac038e..ca70eec 100644 --- a/lib/saml2.coffee +++ b/lib/saml2.coffee @@ -182,12 +182,11 @@ extract_certificate_data = (certificate) -> # verify the signature is signing the important content, nor is it preventing the parsing of unsigned content. check_saml_signature = (xml, certificate) -> doc = (new xmldom.DOMParser()).parseFromString(xml) - signature = xmlcrypto.xpath(doc, "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']") return null unless signature.length is 1 sig = new xmlcrypto.SignedXml() sig.keyInfoProvider = getKey: -> format_pem(certificate, 'CERTIFICATE') - sig.loadSignature signature[0].toString() + sig.loadSignature signature[0] valid = sig.checkSignature xml if valid return get_signed_data(doc, sig.references) diff --git a/test/data/good_response_twice_signed_dsig_ns_at_top.xml b/test/data/good_response_twice_signed_dsig_ns_at_top.xml new file mode 100644 index 0000000..ea2591d --- /dev/null +++ b/test/data/good_response_twice_signed_dsig_ns_at_top.xml @@ -0,0 +1,39 @@ + + + + + VmOQiP59NeSBPwrhe5MDQJlNw/E=pPycwjnj6ezRb9vrmEQ0CTBlkRa7inhDCHUj2Z5s6pOuBZq2bdxY1jvplHz5FW6/2SPtsST5Wj6RZMClHGV8rlTBjgA92+EtGJHgaZYemvFTA1n/7SWI9vjP2Doy9JF8AeZlmN9xgZL/wVsKkdv/lk7B6stWfUI/PDRN5JVUYDvoSC2j1pxkdJ6zhFL9XWs9wUNlO2vsP1XsHrQ7ndn4h5K6J9frfc0IX6R7NBu/pDUk2Vx6Xh1RlhuZRD33KN38e58vs1qm1isFcoTgMhdAVjS41yf92b5KFuDp0x4dliV099QUZFtNH+7SH7pJXEkeLQnXpF/73jXLoMUjdn7qNQ== +MIIDGTCCAgGgAwIBAgIJAO8HJfrb3JZeMA0GCSqGSIb3DQEBBQUAMCMxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDAzMTgwMTE3MTdaFw0yNDAzMTcwMTE3MTdaMCMxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFf1kCef6FTPMxQSoThAZGFNmixh8fRDLsUo58pEFwztBRUPWS6s6Ql8mA75aAEdo4+JVyE8QPi5F+fWbnToWkIw7E7YGl6s+EScSMQYHKCLq4mPHPMHtZspFowNp+Vax88SSUo1TKlpVNVIGim8JQ5SRi3p0aD6UAiu9WxQ5s+xHnDwgvQiu3Sa4COl5NQjkC1r2LrhJnJQQiw0hsn1nGgg15jEaDCZa8uPw1EtHv8smoZpjTbwRBVjXtzLskYIRyYLQjvqR+/QAd0XZcav0LdTwQR6obg/CwSgv7qG/WN6t25VIIGQDIUkVMBhLDmCh8QRpTvx1YWumSWW4D2k2kCAwEAAaNQME4wHQYDVR0OBBYEFLpo8Vz1m19xvPmzx+2wf2PaSTIpMB8GA1UdIwQYMBaAFLpo8Vz1m19xvPmzx+2wf2PaSTIpMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBALhwpLS6C+97nWrEICI5yetQjexCJGltMESg1llNYjsbIuJ/S4XbrVzhN4nfNGMSbj8rb/9FT6TSru5QLjJQQmj38pqsWtEhR2vBLclqGqEcJfvPMdn1qAJhJfhrs0KUpsX6xFTnSkNoyGxCP8Wh2C1L0NL5r+x58lkma5vL6ncwWYY+0C3bt1XbBRdeOZHUwuYTIcD+BCNixQiNor7KjO1TzpOb6V3m1SKHu8idDM5fUcKooGbV3WuE7AJrAG5fvt59V9MtMPc2FklVFminfTeYKboEaxZJxuPDbQs2IyJ/0lI8P0Mv4LIKj4+OipQ/fGbZuE7cOioPKKl02dE7eCA= + + + + + This data has no meaning. + http://idp.example.com/metadata.xml + + + nS72XwOKD7SxpBrvb8MFkrmrPJM=cf4xvQneMFGQOsIgG/xrg8dpYbCvBZ5GUZkIMNA7BTT2tBuiP0djR/iS4uHPqnkbYLVnJd2gwh7Mg/7GySAVSSimfsNUk0LxKd59Nmw8z+iVTKzFnK7O6r4ifkPvWpIM28J1fJmqUINXRXBD1JQSY2p/4TPS1DQAUpYf8Yh1R4SWX0Xqiu2XgIrTXVrqh3X76fm4XMFmyL7FNt1wn8qzobqpfDYciNz1ZCfg9NwdFY4AeWSD3HeByJn9ct0CgNyDu5B6ii4CldfEUS6S15IlicuVimVteNXcSbyNN9/EOkBjCk9PtzgqzX5X4T0rF5CU6s2dSUAjCsmIEPWUr38B/w== +MIIDGTCCAgGgAwIBAgIJAO8HJfrb3JZeMA0GCSqGSIb3DQEBBQUAMCMxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDAzMTgwMTE3MTdaFw0yNDAzMTcwMTE3MTdaMCMxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFf1kCef6FTPMxQSoThAZGFNmixh8fRDLsUo58pEFwztBRUPWS6s6Ql8mA75aAEdo4+JVyE8QPi5F+fWbnToWkIw7E7YGl6s+EScSMQYHKCLq4mPHPMHtZspFowNp+Vax88SSUo1TKlpVNVIGim8JQ5SRi3p0aD6UAiu9WxQ5s+xHnDwgvQiu3Sa4COl5NQjkC1r2LrhJnJQQiw0hsn1nGgg15jEaDCZa8uPw1EtHv8smoZpjTbwRBVjXtzLskYIRyYLQjvqR+/QAd0XZcav0LdTwQR6obg/CwSgv7qG/WN6t25VIIGQDIUkVMBhLDmCh8QRpTvx1YWumSWW4D2k2kCAwEAAaNQME4wHQYDVR0OBBYEFLpo8Vz1m19xvPmzx+2wf2PaSTIpMB8GA1UdIwQYMBaAFLpo8Vz1m19xvPmzx+2wf2PaSTIpMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBALhwpLS6C+97nWrEICI5yetQjexCJGltMESg1llNYjsbIuJ/S4XbrVzhN4nfNGMSbj8rb/9FT6TSru5QLjJQQmj38pqsWtEhR2vBLclqGqEcJfvPMdn1qAJhJfhrs0KUpsX6xFTnSkNoyGxCP8Wh2C1L0NL5r+x58lkma5vL6ncwWYY+0C3bt1XbBRdeOZHUwuYTIcD+BCNixQiNor7KjO1TzpOb6V3m1SKHu8idDM5fUcKooGbV3WuE7AJrAG5fvt59V9MtMPc2FklVFminfTeYKboEaxZJxuPDbQs2IyJ/0lI8P0Mv4LIKj4+OipQ/fGbZuE7cOioPKKl02dE7eCA= + + tstudent + + + + + + + https://sp.example.com/metadata.xml + + + + + Test + + + + + urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + + + + \ No newline at end of file diff --git a/test/saml2.coffee b/test/saml2.coffee index 555469c..bc689af 100644 --- a/test/saml2.coffee +++ b/test/saml2.coffee @@ -187,6 +187,10 @@ describe 'saml2', -> it 'validates a Response signature when a signature also exists within the Assertion', -> assert.notEqual null, saml2.check_saml_signature(get_test_file("good_response_twice_signed.xml"), get_test_file("test.crt")) + it 'validates a Response signature when the dsig namespace is declared at the root level', -> + result = saml2.check_saml_signature(get_test_file("good_response_twice_signed_dsig_ns_at_top.xml"), get_test_file("test.crt")) + assert.notEqual null, result + describe 'check_status_success', => it 'accepts a valid success status', => assert saml2.check_status_success(@good_response_dom), "Did not get 'true' for valid response." From 5d92dc502b3a5db9ba76cd54c8240cd76ebee55d Mon Sep 17 00:00:00 2001 From: r0bot Date: Thu, 29 Nov 2018 15:32:44 +0200 Subject: [PATCH 02/11] No signature authn xml method added. --- lib/saml2.coffee | 10 ++++++++++ test/saml2.coffee | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/saml2.coffee b/lib/saml2.coffee index ca70eec..155f0f3 100644 --- a/lib/saml2.coffee +++ b/lib/saml2.coffee @@ -544,6 +544,16 @@ module.exports.ServiceProvider = { id, xml } = create_authn_request @entity_id, @assert_endpoint, identity_provider.sso_login_url, options.force_authn, options.auth_context, options.nameid_format return sign_authn_request(xml, @private_key, options) + # Returns: + # An xml string with an AuthnRequest without an embedded signature + # Params: + # identity_provider + # options + create_authn_request_xml_no_signature: (identity_provider, options) -> + options = set_option_defaults options, identity_provider.shared_options, @shared_options + { id, xml } = create_authn_request @entity_id, @assert_endpoint, identity_provider.sso_login_url, options.force_authn, options.auth_context, options.nameid_format + return xml + # Returns: # An object containing the parsed response for a redirect assert. # This type of assert inflates the response before parsing it. diff --git a/test/saml2.coffee b/test/saml2.coffee index bc689af..54cb2b0 100644 --- a/test/saml2.coffee +++ b/test/saml2.coffee @@ -1154,5 +1154,22 @@ describe 'saml2', -> method = dom.getElementsByTagName('SignatureMethod')[0] assert.equal method.attributes[0].value, 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' + it 'can create a unsigned AuthnRequest xml document', () -> + sp_options = + entity_id: 'https://sp.example.com/metadata.xml' + private_key: get_test_file('test.pem') + certificate: get_test_file('test.crt') + assert_endpoint: 'https://sp.example.com/assert' + idp_options = + sso_login_url: 'https://idp.example.com/login' + sso_logout_url: 'https://idp.example.com/logout' + certificates: 'other_service_cert' + sp = new saml2.ServiceProvider sp_options + idp = new saml2.IdentityProvider idp_options + xml = sp.create_authn_request_xml_no_signature(idp) + dom = (new xmldom.DOMParser()).parseFromString xml + method = dom.getElementsByTagName('SignatureMethod')[0] + assert.equal method, null + it 'can create metadata', (done) -> done() From 06f32702d2beb2df6668dd3fd42836a14b2b561f Mon Sep 17 00:00:00 2001 From: r0bot Date: Wed, 16 Jan 2019 15:08:14 +0200 Subject: [PATCH 03/11] Lib-js removed from git ignore in order to be used in teh repo directly. --- .gitignore | 1 - lib-js/saml2.js | 982 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 982 insertions(+), 1 deletion(-) create mode 100644 lib-js/saml2.js diff --git a/.gitignore b/.gitignore index d15d0f4..07e81b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ *~ node_modules -lib-js lib-js-cov *.html diff --git a/lib-js/saml2.js b/lib-js/saml2.js new file mode 100644 index 0000000..59fbd1d --- /dev/null +++ b/lib-js/saml2.js @@ -0,0 +1,982 @@ +// Generated by CoffeeScript 1.12.7 +var IdentityProvider, SAMLError, ServiceProvider, SignedXml, XMLNS, _, add_namespaces_to_child_assertions, async, certificate_to_keyinfo, check_saml_signature, check_status_success, create_authn_request, create_logout_request, create_logout_response, create_metadata, crypto, debug, decrypt_assertion, extract_certificate_data, format_pem, get_attribute_value, get_name_id, get_session_info, get_signed_data, get_status, parseString, parse_assertion_attributes, parse_authn_response, parse_logout_request, parse_response_header, pretty_assertion_attributes, set_option_defaults, sign_authn_request, sign_request, to_error, url, util, xmlbuilder, xmlcrypto, xmldom, xmlenc, zlib, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice, + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + +_ = require('underscore'); + +async = require('async'); + +crypto = require('crypto'); + +debug = require('debug')('saml2'); + +parseString = require('xml2js').parseString; + +url = require('url'); + +util = require('util'); + +xmlbuilder = require('xmlbuilder'); + +xmlcrypto = require('xml-crypto'); + +xmldom = require('xmldom'); + +xmlenc = require('xml-encryption'); + +zlib = require('zlib'); + +SignedXml = require('xml-crypto').SignedXml; + +XMLNS = { + SAML: 'urn:oasis:names:tc:SAML:2.0:assertion', + SAMLP: 'urn:oasis:names:tc:SAML:2.0:protocol', + MD: 'urn:oasis:names:tc:SAML:2.0:metadata', + DS: 'http://www.w3.org/2000/09/xmldsig#', + XENC: 'http://www.w3.org/2001/04/xmlenc#', + EXC_C14N: 'http://www.w3.org/2001/10/xml-exc-c14n#' +}; + +SAMLError = (function(superClass) { + extend(SAMLError, superClass); + + function SAMLError(message, extra) { + this.message = message; + this.extra = extra; + SAMLError.__super__.constructor.call(this, this.message); + } + + return SAMLError; + +})(Error); + +create_authn_request = function(issuer, assert_endpoint, destination, force_authn, context, nameid_format) { + var context_element, id, xml; + if (context != null) { + context_element = _(context.class_refs).map(function(class_ref) { + return { + 'saml:AuthnContextClassRef': class_ref + }; + }); + context_element.push({ + '@Comparison': context.comparison + }); + } + id = '_' + crypto.randomBytes(21).toString('hex'); + xml = xmlbuilder.create({ + AuthnRequest: { + '@xmlns': XMLNS.SAMLP, + '@xmlns:saml': XMLNS.SAML, + '@Version': '2.0', + '@ID': id, + '@IssueInstant': (new Date()).toISOString(), + '@Destination': destination, + '@AssertionConsumerServiceURL': assert_endpoint, + '@ProtocolBinding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', + '@ForceAuthn': force_authn, + 'saml:Issuer': issuer, + NameIDPolicy: { + '@Format': nameid_format || 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified', + '@AllowCreate': 'true' + }, + RequestedAuthnContext: context_element + } + }).end(); + return { + id: id, + xml: xml + }; +}; + +sign_authn_request = function(xml, private_key, options) { + var signer; + signer = new SignedXml(null, options); + signer.addReference("//*[local-name(.)='AuthnRequest']", ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#']); + signer.signingKey = private_key; + signer.computeSignature(xml); + return signer.getSignedXml(); +}; + +create_metadata = function(entity_id, assert_endpoint, signing_certificates, encryption_certificates) { + var encryption_cert_descriptors, encryption_certificate, signing_cert_descriptors, signing_certificate; + signing_cert_descriptors = (function() { + var j, len, ref1, results; + ref1 = signing_certificates || []; + results = []; + for (j = 0, len = ref1.length; j < len; j++) { + signing_certificate = ref1[j]; + results.push({ + 'md:KeyDescriptor': certificate_to_keyinfo('signing', signing_certificate) + }); + } + return results; + })(); + encryption_cert_descriptors = (function() { + var j, len, ref1, results; + ref1 = encryption_certificates || []; + results = []; + for (j = 0, len = ref1.length; j < len; j++) { + encryption_certificate = ref1[j]; + results.push({ + 'md:KeyDescriptor': certificate_to_keyinfo('encryption', encryption_certificate) + }); + } + return results; + })(); + return xmlbuilder.create({ + 'md:EntityDescriptor': { + '@xmlns:md': XMLNS.MD, + '@xmlns:ds': XMLNS.DS, + '@entityID': entity_id, + '@validUntil': (new Date(Date.now() + 1000 * 60 * 60)).toISOString(), + 'md:SPSSODescriptor': [].concat({ + '@protocolSupportEnumeration': 'urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol' + }).concat(signing_cert_descriptors).concat(encryption_cert_descriptors).concat([ + { + 'md:SingleLogoutService': { + '@Binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', + '@Location': assert_endpoint + }, + 'md:AssertionConsumerService': { + '@Binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', + '@Location': assert_endpoint, + '@index': '0' + } + } + ]) + } + }).end(); +}; + +create_logout_request = function(issuer, name_id, session_index, destination) { + var id, xml; + id = '_' + crypto.randomBytes(21).toString('hex'); + xml = xmlbuilder.create({ + 'samlp:LogoutRequest': { + '@xmlns:samlp': XMLNS.SAMLP, + '@xmlns:saml': XMLNS.SAML, + '@ID': id, + '@Version': '2.0', + '@IssueInstant': (new Date()).toISOString(), + '@Destination': destination, + 'saml:Issuer': issuer, + 'saml:NameID': name_id, + 'samlp:SessionIndex': session_index + } + }).end(); + return { + id: id, + xml: xml + }; +}; + +create_logout_response = function(issuer, in_response_to, destination, status) { + if (status == null) { + status = 'urn:oasis:names:tc:SAML:2.0:status:Success'; + } + return xmlbuilder.create({ + 'samlp:LogoutResponse': { + '@Destination': destination, + '@ID': '_' + crypto.randomBytes(21).toString('hex'), + '@InResponseTo': in_response_to, + '@IssueInstant': (new Date()).toISOString(), + '@Version': '2.0', + '@xmlns:samlp': XMLNS.SAMLP, + '@xmlns:saml': XMLNS.SAML, + 'saml:Issuer': issuer, + 'samlp:Status': { + 'samlp:StatusCode': { + '@Value': status + } + } + } + }, { + headless: true + }).end(); +}; + +format_pem = function(key, type) { + if ((/-----BEGIN [0-9A-Z ]+-----[^-]*-----END [0-9A-Z ]+-----/g.exec(key)) != null) { + return key; + } + return ("-----BEGIN " + (type.toUpperCase()) + "-----\n") + key.match(/.{1,64}/g).join("\n") + ("\n-----END " + (type.toUpperCase()) + "-----"); +}; + +sign_request = function(saml_request, private_key, relay_state, response) { + var action, data, relay_state_data, samlQueryString, saml_request_data, sigalg_data, sign; + if (response == null) { + response = false; + } + action = response ? "SAMLResponse" : "SAMLRequest"; + data = (action + "=") + encodeURIComponent(saml_request); + if (relay_state) { + data += "&RelayState=" + encodeURIComponent(relay_state); + } + data += "&SigAlg=" + encodeURIComponent('http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'); + saml_request_data = (action + "=") + encodeURIComponent(saml_request); + relay_state_data = relay_state != null ? "&RelayState=" + encodeURIComponent(relay_state) : ""; + sigalg_data = "&SigAlg=" + encodeURIComponent('http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'); + sign = crypto.createSign('RSA-SHA256'); + sign.update(saml_request_data + relay_state_data + sigalg_data); + samlQueryString = {}; + if (response) { + samlQueryString.SAMLResponse = saml_request; + } else { + samlQueryString.SAMLRequest = saml_request; + } + if (relay_state) { + samlQueryString.RelayState = relay_state; + } + samlQueryString.SigAlg = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; + samlQueryString.Signature = sign.sign(format_pem(private_key, 'PRIVATE KEY'), 'base64'); + return samlQueryString; +}; + +certificate_to_keyinfo = function(use, certificate) { + return { + '@use': use, + 'ds:KeyInfo': { + '@xmlns:ds': XMLNS.DS, + 'ds:X509Data': { + 'ds:X509Certificate': extract_certificate_data(certificate) + } + } + }; +}; + +extract_certificate_data = function(certificate) { + var cert_data; + cert_data = /-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g.exec(certificate); + cert_data = cert_data != null ? cert_data[1] : certificate; + if (cert_data == null) { + throw new Error('Invalid Certificate'); + } + return cert_data.replace(/[\r\n]/g, ''); +}; + +check_saml_signature = function(xml, certificate) { + var doc, sig, signature, valid; + doc = (new xmldom.DOMParser()).parseFromString(xml); + signature = xmlcrypto.xpath(doc, "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']"); + if (signature.length !== 1) { + return null; + } + sig = new xmlcrypto.SignedXml(); + sig.keyInfoProvider = { + getKey: function() { + return format_pem(certificate, 'CERTIFICATE'); + } + }; + sig.loadSignature(signature[0]); + valid = sig.checkSignature(xml); + if (valid) { + return get_signed_data(doc, sig.references); + } else { + return null; + } +}; + +get_signed_data = function(doc, references) { + return _.map(references, function(ref) { + var elem, idAttribute, j, len, ref1, uri; + uri = ref.uri; + if (uri[0] === '#') { + uri = uri.substring(1); + } + elem = []; + if (uri === "") { + elem = xmlcrypto.xpath(doc, "//*"); + } else { + ref1 = ["Id", "ID"]; + for (j = 0, len = ref1.length; j < len; j++) { + idAttribute = ref1[j]; + elem = xmlcrypto.xpath(doc, "//*[@*[local-name(.)='" + idAttribute + "']='" + uri + "']"); + if (elem.length > 0) { + break; + } + } + } + if (!(elem.length > 0)) { + throw new Error("Invalid signature; must be a reference to '" + ref.uri + "'"); + } + return elem[0].toString(); + }); +}; + +check_status_success = function(dom) { + var j, len, ref1, status, status_code; + status = dom.getElementsByTagNameNS(XMLNS.SAMLP, 'Status'); + if (status.length !== 1) { + return false; + } + ref1 = status[0].childNodes || []; + for (j = 0, len = ref1.length; j < len; j++) { + status_code = ref1[j]; + if (status_code.attributes != null) { + status = get_attribute_value(status_code, 'Value'); + return status === 'urn:oasis:names:tc:SAML:2.0:status:Success'; + } + } + return false; +}; + +get_status = function(dom) { + var j, l, len, len1, ref1, ref2, status, status_code, status_list, sub_status_code, top_status; + status_list = {}; + status = dom.getElementsByTagNameNS(XMLNS.SAMLP, 'Status'); + if (status.length !== 1) { + return status_list; + } + ref1 = status[0].childNodes || []; + for (j = 0, len = ref1.length; j < len; j++) { + status_code = ref1[j]; + if (status_code.attributes != null) { + top_status = get_attribute_value(status_code, 'Value'); + if (status_list[top_status] == null) { + status_list[top_status] = []; + } + } + ref2 = status_code.childNodes || []; + for (l = 0, len1 = ref2.length; l < len1; l++) { + sub_status_code = ref2[l]; + if ((sub_status_code != null ? sub_status_code.attributes : void 0) != null) { + status = get_attribute_value(sub_status_code, 'Value'); + status_list[top_status].push(status); + } + } + } + return status_list; +}; + +to_error = function(err) { + if (err == null) { + return null; + } + if (!(err instanceof Error)) { + return new Error(util.inspect(err)); + } + return err; +}; + +decrypt_assertion = function(dom, private_keys, cb) { + var encrypted_assertion, encrypted_data, err, errors; + cb = _.wrap(cb, function() { + var args, err, fn; + fn = arguments[0], err = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + return setTimeout((function() { + return fn.apply(null, [to_error(err)].concat(slice.call(args))); + }), 0); + }); + try { + encrypted_assertion = dom.getElementsByTagNameNS(XMLNS.SAML, 'EncryptedAssertion'); + if (encrypted_assertion.length !== 1) { + return cb(new Error("Expected 1 EncryptedAssertion; found " + encrypted_assertion.length + ".")); + } + encrypted_data = encrypted_assertion[0].getElementsByTagNameNS(XMLNS.XENC, 'EncryptedData'); + if (encrypted_data.length !== 1) { + return cb(new Error("Expected 1 EncryptedData inside EncryptedAssertion; found " + encrypted_data.length + ".")); + } + encrypted_assertion = encrypted_assertion[0].toString(); + errors = []; + return async.eachOfSeries(private_keys, function(private_key, index, cb_e) { + return xmlenc.decrypt(encrypted_assertion, { + key: format_pem(private_key, 'PRIVATE KEY') + }, function(err, result) { + if (err != null) { + if (err != null) { + errors.push(new Error("Decrypt failed: " + (util.inspect(err)))); + } + return cb_e(); + } + debug("Decryption successful with private key #" + index + "."); + return cb(null, result); + }); + }, function() { + return cb(new Error("Failed to decrypt assertion with provided key(s): " + (util.inspect(errors)))); + }); + } catch (error) { + err = error; + return cb(new Error("Decrypt failed: " + (util.inspect(err)))); + } +}; + +parse_response_header = function(dom) { + var j, len, ref1, response, response_header, response_type, version; + ref1 = ['Response', 'LogoutResponse', 'LogoutRequest']; + for (j = 0, len = ref1.length; j < len; j++) { + response_type = ref1[j]; + response = dom.getElementsByTagNameNS(XMLNS.SAMLP, response_type); + if (response.length > 0) { + break; + } + } + if (response.length !== 1) { + throw new Error("Expected 1 Response; found " + response.length); + } + response_header = { + version: get_attribute_value(response[0], 'Version'), + destination: get_attribute_value(response[0], 'Destination'), + in_response_to: get_attribute_value(response[0], 'InResponseTo'), + id: get_attribute_value(response[0], 'ID') + }; + version = response_header.version || '2.0'; + if (version !== "2.0") { + throw new Error("Invalid SAML Version " + version); + } + return response_header; +}; + +get_name_id = function(dom) { + var assertion, nameid, ref1, subject; + assertion = dom.getElementsByTagNameNS(XMLNS.SAML, 'Assertion'); + if (assertion.length !== 1) { + throw new Error("Expected 1 Assertion; found " + assertion.length); + } + subject = assertion[0].getElementsByTagNameNS(XMLNS.SAML, 'Subject'); + if (subject.length !== 1) { + throw new Error("Expected 1 Subject; found " + subject.length); + } + nameid = subject[0].getElementsByTagNameNS(XMLNS.SAML, 'NameID'); + if (nameid.length !== 1) { + return null; + } + return (ref1 = nameid[0].firstChild) != null ? ref1.data : void 0; +}; + +get_attribute_value = function(node, attributeName) { + var attribute, attributes, ref1; + attributes = node.attributes || []; + attribute = _.filter(attributes, function(attr) { + return attr.name === attributeName; + }); + return (ref1 = attribute[0]) != null ? ref1.value : void 0; +}; + +get_session_info = function(dom, index_required) { + var assertion, authn_statement, info; + if (index_required == null) { + index_required = true; + } + assertion = dom.getElementsByTagNameNS(XMLNS.SAML, 'Assertion'); + if (assertion.length !== 1) { + throw new Error("Expected 1 Assertion; found " + assertion.length); + } + authn_statement = assertion[0].getElementsByTagNameNS(XMLNS.SAML, 'AuthnStatement'); + if (authn_statement.length !== 1) { + throw new Error("Expected 1 AuthnStatement; found " + authn_statement.length); + } + info = { + index: get_attribute_value(authn_statement[0], 'SessionIndex'), + not_on_or_after: get_attribute_value(authn_statement[0], 'SessionNotOnOrAfter') + }; + if (index_required && (info.index == null)) { + throw new Error("SessionIndex not an attribute of AuthnStatement."); + } + return info; +}; + +parse_assertion_attributes = function(dom) { + var assertion, assertion_attributes, attribute, attribute_name, attribute_statement, attribute_values, j, len, ref1; + assertion = dom.getElementsByTagNameNS(XMLNS.SAML, 'Assertion'); + if (assertion.length !== 1) { + throw new Error("Expected 1 Assertion; found " + assertion.length); + } + attribute_statement = assertion[0].getElementsByTagNameNS(XMLNS.SAML, 'AttributeStatement'); + if (!(attribute_statement.length <= 1)) { + throw new Error("Expected 1 AttributeStatement inside Assertion; found " + attribute_statement.length); + } + if (attribute_statement.length === 0) { + return {}; + } + assertion_attributes = {}; + ref1 = attribute_statement[0].getElementsByTagNameNS(XMLNS.SAML, 'Attribute'); + for (j = 0, len = ref1.length; j < len; j++) { + attribute = ref1[j]; + attribute_name = get_attribute_value(attribute, 'Name'); + if (attribute_name == null) { + throw new Error("Invalid attribute without name"); + } + attribute_values = attribute.getElementsByTagNameNS(XMLNS.SAML, 'AttributeValue'); + assertion_attributes[attribute_name] = _(attribute_values).map(function(attribute_value) { + var ref2; + return ((ref2 = attribute_value.childNodes[0]) != null ? ref2.data : void 0) || ''; + }); + } + return assertion_attributes; +}; + +pretty_assertion_attributes = function(assertion_attributes) { + var claim_map; + claim_map = { + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": "email", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname": "given_name", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "name", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn": "upn", + "http://schemas.xmlsoap.org/claims/CommonName": "common_name", + "http://schemas.xmlsoap.org/claims/Group": "group", + "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "role", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname": "surname", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier": "ppid", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "name_id", + "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod": "authentication_method", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid": "deny_only_group_sid", + "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid": "deny_only_primary_sid", + "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid": "deny_only_primary_group_sid", + "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid": "group_sid", + "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid": "primary_group_sid", + "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid": "primary_sid", + "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname": "windows_account_name" + }; + return _(assertion_attributes).chain().pairs().filter(function(arg) { + var k, v; + k = arg[0], v = arg[1]; + return (claim_map[k] != null) && v.length > 0; + }).map(function(arg) { + var k, v; + k = arg[0], v = arg[1]; + return [claim_map[k], v[0]]; + }).object().value(); +}; + +add_namespaces_to_child_assertions = function(xml_string) { + var assertion_element, assertion_elements, attr, doc, inclusive_namespaces, j, len, namespaces, new_attribute, ns, prefixList, ref1, response_element, response_elements; + doc = new xmldom.DOMParser().parseFromString(xml_string); + response_elements = doc.getElementsByTagNameNS(XMLNS.SAMLP, 'Response'); + if (response_elements.length !== 1) { + return xml_string; + } + response_element = response_elements[0]; + assertion_elements = response_element.getElementsByTagNameNS(XMLNS.SAML, 'Assertion'); + if (assertion_elements.length !== 1) { + return xml_string; + } + assertion_element = assertion_elements[0]; + inclusive_namespaces = assertion_element.getElementsByTagNameNS(XMLNS.EXC_C14N, 'InclusiveNamespaces')[0]; + namespaces = inclusive_namespaces && (prefixList = (ref1 = inclusive_namespaces.getAttribute('PrefixList')) != null ? ref1.trim() : void 0) ? (function() { + var j, len, ref2, results; + ref2 = prefixList.split(' '); + results = []; + for (j = 0, len = ref2.length; j < len; j++) { + ns = ref2[j]; + results.push("xmlns:" + ns); + } + return results; + })() : (function() { + var j, len, ref2, results; + ref2 = response_element.attributes; + results = []; + for (j = 0, len = ref2.length; j < len; j++) { + attr = ref2[j]; + if (attr.name.match(/^xmlns:/)) { + results.push(attr.name); + } + } + return results; + })(); + for (j = 0, len = namespaces.length; j < len; j++) { + ns = namespaces[j]; + if (response_element.getAttribute(ns) && !assertion_element.getAttribute(ns)) { + new_attribute = doc.createAttribute(ns); + new_attribute.value = response_element.getAttribute(ns); + assertion_element.setAttributeNode(new_attribute); + } + } + return new xmldom.XMLSerializer().serializeToString(response_element); +}; + +parse_authn_response = function(saml_response, sp_private_keys, idp_certificates, allow_unencrypted, ignore_signature, require_session_index, cb) { + var user; + user = {}; + return async.waterfall([ + function(cb_wf) { + return decrypt_assertion(saml_response, sp_private_keys, function(err, result) { + var assertion; + if (err == null) { + return cb_wf(null, result); + } + if (!allow_unencrypted) { + return cb_wf(err, result); + } + assertion = saml_response.getElementsByTagNameNS(XMLNS.SAML, 'Assertion'); + if (assertion.length !== 1) { + return cb_wf(new Error("Expected 1 Assertion or 1 EncryptedAssertion; found " + assertion.length)); + } + return cb_wf(null, assertion[0].toString()); + }); + }, function(result, cb_wf) { + var assertion, cert, ex, i, j, l, len, len1, ref1, saml_response_str, sd, signed_data, signed_dom; + debug(result); + if (ignore_signature) { + return cb_wf(null, (new xmldom.DOMParser()).parseFromString(result)); + } + saml_response_str = saml_response.toString(); + ref1 = idp_certificates || []; + for (i = j = 0, len = ref1.length; j < len; i = ++j) { + cert = ref1[i]; + try { + signed_data = check_saml_signature(result, cert) || check_saml_signature(saml_response_str, cert); + } catch (error) { + ex = error; + return cb_wf(new Error("SAML Assertion signature check failed! (Certificate \#" + (i + 1) + " may be invalid. " + ex.message)); + } + if (!signed_data) { + continue; + } + for (l = 0, len1 = signed_data.length; l < len1; l++) { + sd = signed_data[l]; + signed_dom = (new xmldom.DOMParser()).parseFromString(sd); + assertion = signed_dom.getElementsByTagNameNS(XMLNS.SAML, 'Assertion'); + if (assertion.length === 1) { + return cb_wf(null, signed_dom); + } + } + return cb_wf(new Error("Signed data did not contain a SAML Assertion!")); + } + return cb_wf(new Error("SAML Assertion signature check failed! (checked " + idp_certificates.length + " certificate(s))")); + }, function(decrypted_assertion, cb_wf) { + var assertion_attributes, err, session_info; + try { + session_info = get_session_info(decrypted_assertion, require_session_index); + user.name_id = get_name_id(decrypted_assertion); + user.session_index = session_info.index; + if (session_info.not_on_or_after != null) { + user.session_not_on_or_after = session_info.not_on_or_after; + } + assertion_attributes = parse_assertion_attributes(decrypted_assertion); + user = _.extend(user, pretty_assertion_attributes(assertion_attributes)); + user = _.extend(user, { + attributes: assertion_attributes + }); + return cb_wf(null, { + user: user + }); + } catch (error) { + err = error; + return cb_wf(err); + } + } + ], cb); +}; + +parse_logout_request = function(dom) { + var issuer, name_id, ref1, ref2, ref3, request, session_index; + request = dom.getElementsByTagNameNS(XMLNS.SAMLP, "LogoutRequest"); + if (request.length !== 1) { + throw new Error("Expected 1 LogoutRequest; found " + request.length); + } + request = {}; + issuer = dom.getElementsByTagNameNS(XMLNS.SAML, 'Issuer'); + if (issuer.length === 1) { + request.issuer = (ref1 = issuer[0].firstChild) != null ? ref1.data : void 0; + } + name_id = dom.getElementsByTagNameNS(XMLNS.SAML, 'NameID'); + if (name_id.length === 1) { + request.name_id = (ref2 = name_id[0].firstChild) != null ? ref2.data : void 0; + } + session_index = dom.getElementsByTagNameNS(XMLNS.SAMLP, 'SessionIndex'); + if (session_index.length === 1) { + request.session_index = (ref3 = session_index[0].firstChild) != null ? ref3.data : void 0; + } + return request; +}; + +set_option_defaults = function(request_options, idp_options, sp_options) { + return _.defaults({}, request_options, idp_options, sp_options); +}; + +module.exports.ServiceProvider = ServiceProvider = (function() { + function ServiceProvider(options) { + this.create_metadata = bind(this.create_metadata, this); + this.create_logout_request_url = bind(this.create_logout_request_url, this); + this.entity_id = options.entity_id, this.private_key = options.private_key, this.certificate = options.certificate, this.assert_endpoint = options.assert_endpoint, this.alt_private_keys = options.alt_private_keys, this.alt_certs = options.alt_certs; + if (options.audience == null) { + options.audience = this.entity_id; + } + if (options.notbefore_skew == null) { + options.notbefore_skew = 1; + } + this.alt_private_keys = [].concat(this.alt_private_keys || []); + this.alt_certs = [].concat(this.alt_certs || []); + this.shared_options = _(options).pick("force_authn", "auth_context", "nameid_format", "sign_get_request", "allow_unencrypted_assertion", "audience", "notbefore_skew"); + } + + ServiceProvider.prototype.create_login_request_url = function(identity_provider, options, cb) { + var id, ref1, xml; + options = set_option_defaults(options, identity_provider.shared_options, this.shared_options); + ref1 = create_authn_request(this.entity_id, this.assert_endpoint, identity_provider.sso_login_url, options.force_authn, options.auth_context, options.nameid_format), id = ref1.id, xml = ref1.xml; + return zlib.deflateRaw(xml, (function(_this) { + return function(err, deflated) { + var ex, uri; + if (err != null) { + return cb(err); + } + try { + uri = url.parse(identity_provider.sso_login_url, true); + } catch (error) { + ex = error; + return cb(ex); + } + delete uri.search; + if (options.sign_get_request) { + _(uri.query).extend(sign_request(deflated.toString('base64'), _this.private_key, options.relay_state)); + } else { + uri.query.SAMLRequest = deflated.toString('base64'); + if (options.relay_state != null) { + uri.query.RelayState = options.relay_state; + } + } + return cb(null, url.format(uri), id); + }; + })(this)); + }; + + ServiceProvider.prototype.create_authn_request_xml = function(identity_provider, options) { + var id, ref1, xml; + options = set_option_defaults(options, identity_provider.shared_options, this.shared_options); + ref1 = create_authn_request(this.entity_id, this.assert_endpoint, identity_provider.sso_login_url, options.force_authn, options.auth_context, options.nameid_format), id = ref1.id, xml = ref1.xml; + return sign_authn_request(xml, this.private_key, options); + }; + + ServiceProvider.prototype.create_authn_request_xml_no_signature = function(identity_provider, options) { + var id, ref1, xml; + options = set_option_defaults(options, identity_provider.shared_options, this.shared_options); + ref1 = create_authn_request(this.entity_id, this.assert_endpoint, identity_provider.sso_login_url, options.force_authn, options.auth_context, options.nameid_format), id = ref1.id, xml = ref1.xml; + return xml; + }; + + ServiceProvider.prototype.redirect_assert = function(identity_provider, options, cb) { + options = _.defaults(_.extend(options, { + get_request: true + }), { + require_session_index: true + }); + options = set_option_defaults(options, identity_provider.shared_options, this.shared_options); + return this._assert(identity_provider, options, cb); + }; + + ServiceProvider.prototype.post_assert = function(identity_provider, options, cb) { + options = _.defaults(_.extend(options, { + get_request: false + }), { + require_session_index: true + }); + options = set_option_defaults(options, identity_provider.shared_options, this.shared_options); + return this._assert(identity_provider, options, cb); + }; + + ServiceProvider.prototype._assert = function(identity_provider, options, cb) { + var ref1, ref2, response, saml_response; + if (!((((ref1 = options.request_body) != null ? ref1.SAMLResponse : void 0) != null) || (((ref2 = options.request_body) != null ? ref2.SAMLRequest : void 0) != null))) { + return setImmediate(cb, new Error("Request body does not contain SAMLResponse or SAMLRequest.")); + } + if (!_.isNumber(options.notbefore_skew)) { + return setImmediate(cb, new Error("Configuration error: `notbefore_skew` must be a number")); + } + saml_response = null; + response = {}; + return async.waterfall([ + function(cb_wf) { + var raw; + raw = new Buffer(options.request_body.SAMLResponse || options.request_body.SAMLRequest, 'base64'); + if (options.get_request) { + return zlib.inflateRaw(raw, cb_wf); + } + return setImmediate(cb_wf, null, raw); + }, (function(_this) { + return function(response_buffer, cb_wf) { + var attribute, audience_restriction, audiences, condition, conditions, err, j, len, ref3, saml_response_abnormalized, validAudience; + debug(saml_response); + saml_response_abnormalized = add_namespaces_to_child_assertions(response_buffer.toString()); + saml_response = (new xmldom.DOMParser()).parseFromString(saml_response_abnormalized); + try { + response = { + response_header: parse_response_header(saml_response) + }; + } catch (error) { + err = error; + return cb(err); + } + switch (false) { + case saml_response.getElementsByTagNameNS(XMLNS.SAMLP, 'Response').length !== 1: + if (!check_status_success(saml_response)) { + return cb_wf(new SAMLError("SAML Response was not success!", { + status: get_status(saml_response) + })); + } + response.type = 'authn_response'; + conditions = saml_response.getElementsByTagNameNS(XMLNS.SAML, 'Conditions')[0]; + if (conditions != null) { + if (options.ignore_timing !== true) { + ref3 = conditions.attributes; + for (j = 0, len = ref3.length; j < len; j++) { + attribute = ref3[j]; + condition = attribute.name.toLowerCase(); + if (condition === 'notbefore' && Date.parse(attribute.value) > Date.now() + (options.notbefore_skew * 1000)) { + return cb_wf(new SAMLError('SAML Response is not yet valid', { + NotBefore: attribute.value + })); + } + if (condition === 'notonorafter' && Date.parse(attribute.value) <= Date.now()) { + return cb_wf(new SAMLError('SAML Response is no longer valid', { + NotOnOrAfter: attribute.value + })); + } + } + } + audience_restriction = conditions.getElementsByTagNameNS(XMLNS.SAML, 'AudienceRestriction')[0]; + audiences = audience_restriction != null ? audience_restriction.getElementsByTagNameNS(XMLNS.SAML, 'Audience') : void 0; + if ((audiences != null ? audiences.length : void 0) > 0) { + validAudience = _.find(audiences, function(audience) { + var audienceValue, ref4, ref5; + audienceValue = (ref4 = audience.firstChild) != null ? (ref5 = ref4.data) != null ? ref5.trim() : void 0 : void 0; + return !_.isEmpty(audienceValue.trim()) && ((_.isRegExp(options.audience) && options.audience.test(audienceValue)) || (_.isString(options.audience) && options.audience.toLowerCase() === audienceValue.toLowerCase())); + }); + if (validAudience == null) { + return cb_wf(new SAMLError('SAML Response is not valid for this audience')); + } + } + } + return parse_authn_response(saml_response, [_this.private_key].concat(_this.alt_private_keys), identity_provider.certificates, options.allow_unencrypted_assertion, options.ignore_signature, options.require_session_index, cb_wf); + case saml_response.getElementsByTagNameNS(XMLNS.SAMLP, 'LogoutResponse').length !== 1: + if (!check_status_success(saml_response)) { + return cb_wf(new SAMLError("SAML Response was not success!", { + status: get_status(saml_response) + })); + } + response.type = 'logout_response'; + return setImmediate(cb_wf, null, {}); + case saml_response.getElementsByTagNameNS(XMLNS.SAMLP, 'LogoutRequest').length !== 1: + response.type = 'logout_request'; + return setImmediate(cb_wf, null, parse_logout_request(saml_response)); + } + }; + })(this), function(result, cb_wf) { + _.extend(response, result); + return cb_wf(null, response); + } + ], cb); + }; + + ServiceProvider.prototype.create_logout_request_url = function(identity_provider, options, cb) { + var id, ref1, xml; + if (_.isString(identity_provider)) { + identity_provider = { + sso_logout_url: identity_provider, + options: {} + }; + } + options = set_option_defaults(options, identity_provider.shared_options, this.shared_options); + ref1 = create_logout_request(this.entity_id, options.name_id, options.session_index, identity_provider.sso_logout_url), id = ref1.id, xml = ref1.xml; + return zlib.deflateRaw(xml, (function(_this) { + return function(err, deflated) { + var ex, query, uri; + if (err != null) { + return cb(err); + } + try { + uri = url.parse(identity_provider.sso_logout_url, true); + } catch (error) { + ex = error; + return cb(ex); + } + query = null; + if (options.sign_get_request) { + query = sign_request(deflated.toString('base64'), _this.private_key, options.relay_state); + } else { + query = { + SAMLRequest: deflated.toString('base64') + }; + if (options.relay_state != null) { + query.RelayState = options.relay_state; + } + } + uri.query = _.extend(query, uri.query); + uri.search = null; + uri.query = query; + return cb(null, url.format(uri), id); + }; + })(this)); + }; + + ServiceProvider.prototype.create_logout_response_url = function(identity_provider, options, cb) { + var xml; + if (_.isString(identity_provider)) { + identity_provider = { + sso_logout_url: identity_provider, + options: {} + }; + } + options = set_option_defaults(options, identity_provider.shared_options, this.shared_options); + xml = create_logout_response(this.entity_id, options.in_response_to, identity_provider.sso_logout_url); + return zlib.deflateRaw(xml, (function(_this) { + return function(err, deflated) { + var ex, uri; + if (err != null) { + return cb(err); + } + try { + uri = url.parse(identity_provider.sso_logout_url); + } catch (error) { + ex = error; + return cb(ex); + } + if (options.sign_get_request) { + uri.query = sign_request(deflated.toString('base64'), _this.private_key, options.relay_state, true); + } else { + uri.query = { + SAMLResponse: deflated.toString('base64') + }; + if (options.relay_state != null) { + uri.query.RelayState = options.relay_state; + } + } + return cb(null, url.format(uri)); + }; + })(this)); + }; + + ServiceProvider.prototype.create_metadata = function() { + var certs; + certs = [this.certificate].concat(this.alt_certs); + return create_metadata(this.entity_id, this.assert_endpoint, certs, certs); + }; + + return ServiceProvider; + +})(); + +module.exports.IdentityProvider = IdentityProvider = (function() { + function IdentityProvider(options) { + this.sso_login_url = options.sso_login_url, this.sso_logout_url = options.sso_logout_url, this.certificates = options.certificates; + if (!_.isArray(this.certificates)) { + this.certificates = [this.certificates]; + } + this.shared_options = _.pick(options, "force_authn", "sign_get_request", "allow_unencrypted_assertion"); + } + + return IdentityProvider; + +})(); + +if (process.env.NODE_ENV === "test") { + module.exports.create_authn_request = create_authn_request; + module.exports.sign_authn_request = sign_authn_request; + module.exports.create_metadata = create_metadata; + module.exports.format_pem = format_pem; + module.exports.sign_request = sign_request; + module.exports.check_saml_signature = check_saml_signature; + module.exports.check_status_success = check_status_success; + module.exports.pretty_assertion_attributes = pretty_assertion_attributes; + module.exports.decrypt_assertion = decrypt_assertion; + module.exports.parse_response_header = parse_response_header; + module.exports.parse_logout_request = parse_logout_request; + module.exports.get_name_id = get_name_id; + module.exports.get_session_info = get_session_info; + module.exports.parse_assertion_attributes = parse_assertion_attributes; + module.exports.add_namespaces_to_child_assertions = add_namespaces_to_child_assertions; + module.exports.set_option_defaults = set_option_defaults; + module.exports.extract_certificate_data = extract_certificate_data; +} From c23d93b5fc537b5a260f4cb8d6793f34b721c721 Mon Sep 17 00:00:00 2001 From: ivanovit Date: Tue, 5 May 2020 13:08:12 +0300 Subject: [PATCH 04/11] KDEV-647: Some Idp validates the order of elements in SAML Request. --- lib-js/saml2.js | 17 ++++++++++++++--- lib/saml2.coffee | 8 ++++++-- package.json | 2 +- test/saml2.coffee | 6 ++++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/lib-js/saml2.js b/lib-js/saml2.js index 59fbd1d..ffe81d9 100644 --- a/lib-js/saml2.js +++ b/lib-js/saml2.js @@ -1,5 +1,5 @@ // Generated by CoffeeScript 1.12.7 -var IdentityProvider, SAMLError, ServiceProvider, SignedXml, XMLNS, _, add_namespaces_to_child_assertions, async, certificate_to_keyinfo, check_saml_signature, check_status_success, create_authn_request, create_logout_request, create_logout_response, create_metadata, crypto, debug, decrypt_assertion, extract_certificate_data, format_pem, get_attribute_value, get_name_id, get_session_info, get_signed_data, get_status, parseString, parse_assertion_attributes, parse_authn_response, parse_logout_request, parse_response_header, pretty_assertion_attributes, set_option_defaults, sign_authn_request, sign_request, to_error, url, util, xmlbuilder, xmlcrypto, xmldom, xmlenc, zlib, +var IdentityProvider, SAMLError, ServiceProvider, SignedXml, XMLNS, _, add_namespaces_to_child_assertions, async, authnRequestXPath, certificate_to_keyinfo, check_saml_signature, check_status_success, create_authn_request, create_logout_request, create_logout_response, create_metadata, crypto, debug, decrypt_assertion, defaultTransforms, extract_certificate_data, format_pem, get_attribute_value, get_name_id, get_session_info, get_signed_data, get_status, issuerXPath, parseString, parse_assertion_attributes, parse_authn_response, parse_logout_request, parse_response_header, pretty_assertion_attributes, set_option_defaults, sign_authn_request, sign_request, to_error, url, util, xmlbuilder, xmlcrypto, xmldom, xmlenc, zlib, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty, slice = [].slice, @@ -31,6 +31,12 @@ zlib = require('zlib'); SignedXml = require('xml-crypto').SignedXml; +authnRequestXPath = '/*[local-name(.)="AuthnRequest" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:protocol"]'; + +issuerXPath = '/*[local-name(.)="Issuer" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:assertion"]'; + +defaultTransforms = ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#']; + XMLNS = { SAML: 'urn:oasis:names:tc:SAML:2.0:assertion', SAMLP: 'urn:oasis:names:tc:SAML:2.0:protocol', @@ -94,9 +100,14 @@ create_authn_request = function(issuer, assert_endpoint, destination, force_auth sign_authn_request = function(xml, private_key, options) { var signer; signer = new SignedXml(null, options); - signer.addReference("//*[local-name(.)='AuthnRequest']", ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#']); + signer.addReference(authnRequestXPath, defaultTransforms); signer.signingKey = private_key; - signer.computeSignature(xml); + signer.computeSignature(xml, { + location: { + reference: authnRequestXPath + issuerXPath, + action: 'after' + } + }); return signer.getSignedXml(); }; diff --git a/lib/saml2.coffee b/lib/saml2.coffee index 155f0f3..2aa0137 100644 --- a/lib/saml2.coffee +++ b/lib/saml2.coffee @@ -12,6 +12,10 @@ xmlenc = require 'xml-encryption' zlib = require 'zlib' SignedXml = require('xml-crypto').SignedXml +authnRequestXPath = '/*[local-name(.)="AuthnRequest" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:protocol"]'; +issuerXPath = '/*[local-name(.)="Issuer" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:assertion"]'; +defaultTransforms = [ 'http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#' ]; + XMLNS = SAML: 'urn:oasis:names:tc:SAML:2.0:assertion' SAMLP: 'urn:oasis:names:tc:SAML:2.0:protocol' @@ -54,9 +58,9 @@ create_authn_request = (issuer, assert_endpoint, destination, force_authn, conte # Adds an embedded signature to a previously generated AuthnRequest sign_authn_request = (xml, private_key, options) -> signer = new SignedXml null, options - signer.addReference "//*[local-name(.)='AuthnRequest']", ['http://www.w3.org/2000/09/xmldsig#enveloped-signature','http://www.w3.org/2001/10/xml-exc-c14n#'] + signer.addReference authnRequestXPath, defaultTransforms signer.signingKey = private_key - signer.computeSignature xml + signer.computeSignature xml, { location: { reference: authnRequestXPath + issuerXPath, action: 'after' }} return signer.getSignedXml() # Creates metadata and returns it as a string of XML. The metadata has one POST assertion endpoint. diff --git a/package.json b/package.json index da8fff5..9a214c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "saml2-js", - "version": "2.0.0", + "version": "2.0.1", "description": "SAML 2.0 node helpers", "author": "Clever", "main": "index.js", diff --git a/test/saml2.coffee b/test/saml2.coffee index 54cb2b0..4c7e4a4 100644 --- a/test/saml2.coffee +++ b/test/saml2.coffee @@ -1128,6 +1128,12 @@ describe 'saml2', -> xml = sp.create_authn_request_xml(idp) dom = (new xmldom.DOMParser()).parseFromString xml + + authnRequestChildNodes = dom.getElementsByTagName('AuthnRequest')[0].childNodes + assert.equal authnRequestChildNodes[0].tagName, 'saml:Issuer' + assert.equal authnRequestChildNodes[1].tagName, 'Signature' + assert.equal authnRequestChildNodes[2].tagName, 'NameIDPolicy' + method = dom.getElementsByTagName('SignatureMethod')[0] assert.equal method.attributes[0].value, 'http://www.w3.org/2000/09/xmldsig#rsa-sha1' From e627a0be31d040fa52f0b83273b1018a2bd5cef4 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 15 Oct 2020 09:58:58 +0300 Subject: [PATCH 05/11] Fix npm security problems --- package-lock.json | 399 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 +- 2 files changed, 402 insertions(+), 3 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4874569 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,399 @@ +{ + "name": "@progresskinvey/saml2-js", + "version": "2.0.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", + "dev": true + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "lodash-node": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash-node/-/lodash-node-2.4.1.tgz", + "integrity": "sha1-6oL3sQDHM9GkKvdoAeUGEF4qgOw=" + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "requires": { + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + }, + "underscore": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.11.0.tgz", + "integrity": "sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml-crypto": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-0.10.1.tgz", + "integrity": "sha1-+DL3TM9W8kr8rhFjofyrRNlndKg=", + "requires": { + "xmldom": "=0.1.19", + "xpath.js": ">=0.0.3" + }, + "dependencies": { + "xmldom": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.19.tgz", + "integrity": "sha1-Yx/Ad3bv2EEYvyUXGzftTQdaCrw=" + } + } + }, + "xml-encryption": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.1.tgz", + "integrity": "sha512-hn5w3l5p2+nGjlmM0CAhMChDzVGhW+M37jH35Z+GJIipXbn9PUlAIRZ6I5Wm7ynlqZjFrMAr83d/CIp9VZJMTA==", + "requires": { + "escape-html": "^1.0.3", + "node-forge": "^0.10.0", + "xmldom": "~0.1.15", + "xpath": "0.0.27" + } + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "dependencies": { + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + } + } + }, + "xmlbuilder": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.2.1.tgz", + "integrity": "sha1-kyZDDxMNh0NdTECGZDqikm4QWjI=", + "requires": { + "lodash-node": "~2.4.1" + } + }, + "xmldom": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==" + }, + "xpath": { + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==" + }, + "xpath.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", + "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" + } + } +} diff --git a/package.json b/package.json index 9a214c5..eda6e9f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "saml2-js", - "version": "2.0.1", + "name": "@progresskinvey/saml2-js", + "version": "2.0.2", "description": "SAML 2.0 node helpers", "author": "Clever", "main": "index.js", @@ -32,7 +32,7 @@ "debug": "^2.6.0", "underscore": "^1.8.0", "xml-crypto": "^0.10.0", - "xml-encryption": "^0.11.0", + "xml-encryption": "^1.2.1", "xml2js": "^0.4.0", "xmlbuilder": "~2.2.0", "xmldom": "^0.1.0" From da19963e43bec3d3052171240dd26d45e761d09a Mon Sep 17 00:00:00 2001 From: Dimo Mitev Date: Wed, 9 Dec 2020 14:57:42 +0200 Subject: [PATCH 06/11] Bump xml-crypto to latest version in order to fix High npm audir security issue --- package-lock.json | 21 ++++++++------------- package.json | 2 +- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4874569..c20b82f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -330,18 +330,18 @@ "dev": true }, "xml-crypto": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-0.10.1.tgz", - "integrity": "sha1-+DL3TM9W8kr8rhFjofyrRNlndKg=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.0.0.tgz", + "integrity": "sha512-/a04qr7RpONRZHOxROZ6iIHItdsQQjN3sj8lJkYDDss8tAkEaAs0VrFjb3tlhmS5snQru5lTs9/5ISSMdPDHlg==", "requires": { - "xmldom": "=0.1.19", - "xpath.js": ">=0.0.3" + "xmldom": "0.1.27", + "xpath": "0.0.27" }, "dependencies": { "xmldom": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.19.tgz", - "integrity": "sha1-Yx/Ad3bv2EEYvyUXGzftTQdaCrw=" + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", + "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" } } }, @@ -389,11 +389,6 @@ "version": "0.0.27", "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==" - }, - "xpath.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" } } } diff --git a/package.json b/package.json index eda6e9f..7b5ee42 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "async": "^2.5.0", "debug": "^2.6.0", "underscore": "^1.8.0", - "xml-crypto": "^0.10.0", + "xml-crypto": "^2.0.0", "xml-encryption": "^1.2.1", "xml2js": "^0.4.0", "xmlbuilder": "~2.2.0", From d914d764f2e97c02da41d167512620b9c09d743f Mon Sep 17 00:00:00 2001 From: Dimo Mitev Date: Fri, 18 Dec 2020 15:50:58 +0200 Subject: [PATCH 07/11] Fixes after xml-crypto update --- lib-js/saml2.js | 14 +++++++++++--- lib/saml2.coffee | 15 +++++++++++++-- package-lock.json | 2 +- package.json | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib-js/saml2.js b/lib-js/saml2.js index ffe81d9..ca7a7c0 100644 --- a/lib-js/saml2.js +++ b/lib-js/saml2.js @@ -268,10 +268,18 @@ extract_certificate_data = function(certificate) { return cert_data.replace(/[\r\n]/g, ''); }; -check_saml_signature = function(xml, certificate) { - var doc, sig, signature, valid; +check_saml_signature = function(_xml, certificate) { + var doc, maybe_assert, maybe_req, maybe_resp, sig, signature, to_check, valid, xml; + xml = _xml.replace(/\r\n?/g, '\n'); doc = (new xmldom.DOMParser()).parseFromString(xml); - signature = xmlcrypto.xpath(doc, "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']"); + maybe_req = xmlcrypto.xpath(doc, "//*[local-name(.)='AuthnRequest']"); + maybe_req = maybe_req && maybe_req[0]; + maybe_resp = xmlcrypto.xpath(doc, "//*[local-name(.)='Response']"); + maybe_resp = maybe_resp && maybe_resp[0]; + maybe_assert = xmlcrypto.xpath(doc, "//*[local-name(.)='Assertion']"); + maybe_assert = maybe_assert && maybe_assert[0]; + to_check = maybe_req || maybe_resp || maybe_assert; + signature = xmlcrypto.xpath(to_check, "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']"); if (signature.length !== 1) { return null; } diff --git a/lib/saml2.coffee b/lib/saml2.coffee index 2aa0137..23e5ecb 100644 --- a/lib/saml2.coffee +++ b/lib/saml2.coffee @@ -184,9 +184,20 @@ extract_certificate_data = (certificate) -> # This checks the signature of a saml document and returns either array containing the signed data if valid, or null # if the signature is invalid. Comparing the result against null is NOT sufficient for signature checks as it doesn't # verify the signature is signing the important content, nor is it preventing the parsing of unsigned content. -check_saml_signature = (xml, certificate) -> +check_saml_signature = (_xml, certificate) -> + # xml-crypto requires that whitespace is normalized as such: + # https://github.com/yaronn/xml-crypto/commit/17f75c538674c0afe29e766b058004ad23bd5136#diff-5dfe38baf287dcf756a17c2dd63483781b53bf4b669e10efdd01e74bcd8e780aL69 + xml = _xml.replace(/\r\n?/g, '\n') doc = (new xmldom.DOMParser()).parseFromString(xml) - signature = xmlcrypto.xpath(doc, "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']") + # Find the correct section of the XML doc to check the signature for + maybe_req = xmlcrypto.xpath(doc, "//*[local-name(.)='AuthnRequest']") + maybe_req = maybe_req && maybe_req[0] + maybe_resp = xmlcrypto.xpath(doc, "//*[local-name(.)='Response']") + maybe_resp = maybe_resp && maybe_resp[0] + maybe_assert = xmlcrypto.xpath(doc, "//*[local-name(.)='Assertion']") + maybe_assert = maybe_assert && maybe_assert[0] + to_check = maybe_req || maybe_resp || maybe_assert + signature = xmlcrypto.xpath(to_check, "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']") return null unless signature.length is 1 sig = new xmlcrypto.SignedXml() sig.keyInfoProvider = getKey: -> format_pem(certificate, 'CERTIFICATE') diff --git a/package-lock.json b/package-lock.json index c20b82f..da462c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@progresskinvey/saml2-js", - "version": "2.0.2", + "version": "2.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 7b5ee42..4dd1fd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@progresskinvey/saml2-js", - "version": "2.0.2", + "version": "2.0.3", "description": "SAML 2.0 node helpers", "author": "Clever", "main": "index.js", From c91b8624bad2199032222721cf3ef26b10d4c357 Mon Sep 17 00:00:00 2001 From: ventsislav-georgiev Date: Wed, 23 Jun 2021 10:56:24 +0300 Subject: [PATCH 08/11] feat(npm-security): updates --- .npmignore | 1 + package-lock.json | 532 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 4 +- 3 files changed, 501 insertions(+), 36 deletions(-) diff --git a/.npmignore b/.npmignore index 4a7620b..26962bf 100644 --- a/.npmignore +++ b/.npmignore @@ -3,3 +3,4 @@ node_modules lib-js-cov lib *.html +test \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index da462c2..3ab7b20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,479 @@ { "name": "@progresskinvey/saml2-js", - "version": "2.0.3", - "lockfileVersion": 1, + "version": "2.2.0", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "@progresskinvey/saml2-js", + "version": "2.2.0", + "dependencies": { + "async": "^2.5.0", + "debug": "^2.6.0", + "underscore": "^1.8.0", + "xml-crypto": "^2.0.0", + "xml-encryption": "^1.2.1", + "xml2js": "^0.4.0", + "xmlbuilder": "~2.2.0", + "xmldom": "^0.6.0" + }, + "devDependencies": { + "coffee-script": "^1.12.0", + "mocha": "^3.5.0" + }, + "engines": { + "node": ">=0.10.x" + } + }, + "node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "node_modules/coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", + "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "dev": true, + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "dependencies": { + "graceful-readlink": ">= 1.0.0" + }, + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "node_modules/growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "deprecated": "Please use the native JSON object instead of JSON 3", + "dev": true + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-node": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash-node/-/lodash-node-2.4.1.tgz", + "integrity": "sha1-6oL3sQDHM9GkKvdoAeUGEF4qgOw=", + "deprecated": "This package is discontinued. Use lodash@^4.0.0." + }, + "node_modules/lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "node_modules/lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "node_modules/lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "node_modules/lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "dependencies": { + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "dev": true, + "dependencies": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 0.10.x", + "npm": ">= 1.4.x" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/underscore": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", + "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/xml-crypto": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.2.tgz", + "integrity": "sha512-DBhZXtBjENtLwJmeJhLUBwUm9YWNjCRvAx6ESP4VJyM9PDuKqZu2Fp5Y5HKqcdJT7vV7eI25Z4UBMezji6QloQ==", + "dependencies": { + "xmldom": "^0.6.0", + "xpath": "0.0.32" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xml-encryption": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.4.tgz", + "integrity": "sha512-+4aSBIv/lwmv5PntfYsZyelOnCcyDmCt/MNxXUukRGlcWW8DObJ26obbVX3iXYRdqkLqbv3AKk8ntNCGKIq/UQ==", + "dependencies": { + "escape-html": "^1.0.3", + "node-forge": "^0.10.0", + "xmldom": "~0.6.0", + "xpath": "0.0.32" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.2.1.tgz", + "integrity": "sha1-kyZDDxMNh0NdTECGZDqikm4QWjI=", + "dependencies": { + "lodash-node": "~2.4.1" + }, + "engines": { + "node": "0.8.x || 0.10.x" + } + }, + "node_modules/xmldom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", + "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xpath": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", + "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==", + "engines": { + "node": ">=0.6.0" + } + } + }, "dependencies": { "async": { "version": "2.6.3", @@ -13,9 +484,9 @@ } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "brace-expansion": { @@ -147,9 +618,9 @@ "dev": true }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash-node": { "version": "2.4.1", @@ -319,9 +790,9 @@ } }, "underscore": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.11.0.tgz", - "integrity": "sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw==" + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", + "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" }, "wrappy": { "version": "1.0.2", @@ -330,30 +801,23 @@ "dev": true }, "xml-crypto": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.0.0.tgz", - "integrity": "sha512-/a04qr7RpONRZHOxROZ6iIHItdsQQjN3sj8lJkYDDss8tAkEaAs0VrFjb3tlhmS5snQru5lTs9/5ISSMdPDHlg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.2.tgz", + "integrity": "sha512-DBhZXtBjENtLwJmeJhLUBwUm9YWNjCRvAx6ESP4VJyM9PDuKqZu2Fp5Y5HKqcdJT7vV7eI25Z4UBMezji6QloQ==", "requires": { - "xmldom": "0.1.27", - "xpath": "0.0.27" - }, - "dependencies": { - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - } + "xmldom": "^0.6.0", + "xpath": "0.0.32" } }, "xml-encryption": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.1.tgz", - "integrity": "sha512-hn5w3l5p2+nGjlmM0CAhMChDzVGhW+M37jH35Z+GJIipXbn9PUlAIRZ6I5Wm7ynlqZjFrMAr83d/CIp9VZJMTA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.4.tgz", + "integrity": "sha512-+4aSBIv/lwmv5PntfYsZyelOnCcyDmCt/MNxXUukRGlcWW8DObJ26obbVX3iXYRdqkLqbv3AKk8ntNCGKIq/UQ==", "requires": { "escape-html": "^1.0.3", "node-forge": "^0.10.0", - "xmldom": "~0.1.15", - "xpath": "0.0.27" + "xmldom": "~0.6.0", + "xpath": "0.0.32" } }, "xml2js": { @@ -381,14 +845,14 @@ } }, "xmldom": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", + "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==" }, "xpath": { - "version": "0.0.27", - "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", - "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==" + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", + "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==" } } } diff --git a/package.json b/package.json index 4dd1fd6..e322340 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@progresskinvey/saml2-js", - "version": "2.0.3", + "version": "2.2.0", "description": "SAML 2.0 node helpers", "author": "Clever", "main": "index.js", @@ -35,6 +35,6 @@ "xml-encryption": "^1.2.1", "xml2js": "^0.4.0", "xmlbuilder": "~2.2.0", - "xmldom": "^0.1.0" + "xmldom": "^0.6.0" } } From e42ffc92be91cde27f819425fb413fc7d514f7e6 Mon Sep 17 00:00:00 2001 From: Tsvetomir Nedyalkov Date: Wed, 20 Apr 2022 15:59:00 +0300 Subject: [PATCH 09/11] Fixed npm security --- package-lock.json | 500 ++-------------------------------------------- package.json | 6 +- 2 files changed, 17 insertions(+), 489 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3ab7b20..eb07a93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,484 +1,18 @@ { "name": "@progresskinvey/saml2-js", - "version": "2.2.0", - "lockfileVersion": 2, + "version": "2.3.0", + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "@progresskinvey/saml2-js", - "version": "2.2.0", - "dependencies": { - "async": "^2.5.0", - "debug": "^2.6.0", - "underscore": "^1.8.0", - "xml-crypto": "^2.0.0", - "xml-encryption": "^1.2.1", - "xml2js": "^0.4.0", - "xmlbuilder": "~2.2.0", - "xmldom": "^0.6.0" - }, - "devDependencies": { - "coffee-script": "^1.12.0", - "mocha": "^3.5.0" - }, - "engines": { - "node": ">=0.10.x" - } - }, - "node_modules/async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "node_modules/coffee-script": { - "version": "1.12.7", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", - "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", - "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", - "dev": true, - "bin": { - "cake": "bin/cake", - "coffee": "bin/coffee" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "dependencies": { - "graceful-readlink": ">= 1.0.0" - }, - "engines": { - "node": ">= 0.6.x" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "node_modules/growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, - "node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "deprecated": "Please use the native JSON object instead of JSON 3", - "dev": true - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash-node": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash-node/-/lodash-node-2.4.1.tgz", - "integrity": "sha1-6oL3sQDHM9GkKvdoAeUGEF4qgOw=", - "deprecated": "This package is discontinued. Use lodash@^4.0.0." - }, - "node_modules/lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "dependencies": { - "lodash._basecopy": "^3.0.0", - "lodash.keys": "^3.0.0" - } - }, - "node_modules/lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "node_modules/lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, - "node_modules/lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "node_modules/lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "node_modules/lodash.create": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "dependencies": { - "lodash._baseassign": "^3.0.0", - "lodash._basecreate": "^3.0.0", - "lodash._isiterateecall": "^3.0.0" - } - }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "node_modules/lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "node_modules/lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "dependencies": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dev": true, - "dependencies": { - "minimist": "0.0.8" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", - "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", - "dev": true, - "dependencies": { - "browser-stdout": "1.3.0", - "commander": "2.9.0", - "debug": "2.6.8", - "diff": "3.2.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.1", - "growl": "1.9.2", - "he": "1.1.1", - "json3": "3.3.2", - "lodash.create": "3.1.1", - "mkdirp": "0.5.1", - "supports-color": "3.1.2" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 0.10.x", - "npm": ">= 1.4.x" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", - "dev": true, - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/xml-crypto": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.2.tgz", - "integrity": "sha512-DBhZXtBjENtLwJmeJhLUBwUm9YWNjCRvAx6ESP4VJyM9PDuKqZu2Fp5Y5HKqcdJT7vV7eI25Z4UBMezji6QloQ==", - "dependencies": { - "xmldom": "^0.6.0", - "xpath": "0.0.32" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/xml-encryption": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.4.tgz", - "integrity": "sha512-+4aSBIv/lwmv5PntfYsZyelOnCcyDmCt/MNxXUukRGlcWW8DObJ26obbVX3iXYRdqkLqbv3AKk8ntNCGKIq/UQ==", - "dependencies": { - "escape-html": "^1.0.3", - "node-forge": "^0.10.0", - "xmldom": "~0.6.0", - "xpath": "0.0.32" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xml2js/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xmlbuilder": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.2.1.tgz", - "integrity": "sha1-kyZDDxMNh0NdTECGZDqikm4QWjI=", - "dependencies": { - "lodash-node": "~2.4.1" - }, - "engines": { - "node": "0.8.x || 0.10.x" - } - }, - "node_modules/xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/xpath": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", - "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==", - "engines": { - "node": ">=0.6.0" - } - } - }, "dependencies": { + "@xmldom/xmldom": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz", + "integrity": "sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==" + }, "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "requires": { "lodash": "^4.17.14" } @@ -755,11 +289,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -810,13 +339,12 @@ } }, "xml-encryption": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.2.4.tgz", - "integrity": "sha512-+4aSBIv/lwmv5PntfYsZyelOnCcyDmCt/MNxXUukRGlcWW8DObJ26obbVX3iXYRdqkLqbv3AKk8ntNCGKIq/UQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-2.0.0.tgz", + "integrity": "sha512-4Av83DdvAgUQQMfi/w8G01aJshbEZP9ewjmZMpS9t3H+OCZBDvyK4GJPnHGfWiXlArnPbYvR58JB9qF2x9Ds+Q==", "requires": { + "@xmldom/xmldom": "^0.7.0", "escape-html": "^1.0.3", - "node-forge": "^0.10.0", - "xmldom": "~0.6.0", "xpath": "0.0.32" } }, diff --git a/package.json b/package.json index e322340..d482a79 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@progresskinvey/saml2-js", - "version": "2.2.0", + "version": "2.3.0", "description": "SAML 2.0 node helpers", "author": "Clever", "main": "index.js", @@ -28,11 +28,11 @@ "coffee-script": "^1.12.0" }, "dependencies": { - "async": "^2.5.0", + "async": "2.6.4", "debug": "^2.6.0", "underscore": "^1.8.0", "xml-crypto": "^2.0.0", - "xml-encryption": "^1.2.1", + "xml-encryption": "2.0.0", "xml2js": "^0.4.0", "xmlbuilder": "~2.2.0", "xmldom": "^0.6.0" From 62b7c0c7eada099849677776bfc8fd3078b52155 Mon Sep 17 00:00:00 2001 From: Tsvetomir Nedyalkov Date: Thu, 26 Jan 2023 17:32:14 +0200 Subject: [PATCH 10/11] Replace 'xmldom' with '@xmldom/xmldom' to address security issues and update 'xml-crypto' --- lib-js/saml2.js | 2 +- lib/saml2.coffee | 2 +- package-lock.json | 26 ++++++++++++++------------ package.json | 4 ++-- test/saml2.coffee | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/lib-js/saml2.js b/lib-js/saml2.js index ca7a7c0..1a60e52 100644 --- a/lib-js/saml2.js +++ b/lib-js/saml2.js @@ -23,7 +23,7 @@ xmlbuilder = require('xmlbuilder'); xmlcrypto = require('xml-crypto'); -xmldom = require('xmldom'); +xmldom = require('@xmldom/xmldom'); xmlenc = require('xml-encryption'); diff --git a/lib/saml2.coffee b/lib/saml2.coffee index 23e5ecb..d2ec26b 100644 --- a/lib/saml2.coffee +++ b/lib/saml2.coffee @@ -7,7 +7,7 @@ url = require 'url' util = require 'util' xmlbuilder = require 'xmlbuilder' xmlcrypto = require 'xml-crypto' -xmldom = require 'xmldom' +xmldom = require '@xmldom/xmldom' xmlenc = require 'xml-encryption' zlib = require 'zlib' SignedXml = require('xml-crypto').SignedXml diff --git a/package-lock.json b/package-lock.json index eb07a93..d515f3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@xmldom/xmldom": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz", - "integrity": "sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==" + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.7.tgz", + "integrity": "sha512-RwEdIYho2kjbSZ7fpvhkHy5wk1Y3x0O6e/EHL3/SoiAfFWH+yhV2/XZQvsBoAeGRNFwgScJS/gRZv+uIwoj7yA==" }, "async": { "version": "2.6.4", @@ -330,12 +330,19 @@ "dev": true }, "xml-crypto": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.2.tgz", - "integrity": "sha512-DBhZXtBjENtLwJmeJhLUBwUm9YWNjCRvAx6ESP4VJyM9PDuKqZu2Fp5Y5HKqcdJT7vV7eI25Z4UBMezji6QloQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.5.tgz", + "integrity": "sha512-xOSJmGFm+BTXmaPYk8pPV3duKo6hJuZ5niN4uMzoNcTlwYs0jAu/N3qY+ud9MhE4N7eMRuC1ayC7Yhmb7MmAWg==", "requires": { - "xmldom": "^0.6.0", + "@xmldom/xmldom": "^0.7.9", "xpath": "0.0.32" + }, + "dependencies": { + "@xmldom/xmldom": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz", + "integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA==" + } } }, "xml-encryption": { @@ -372,11 +379,6 @@ "lodash-node": "~2.4.1" } }, - "xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==" - }, "xpath": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", diff --git a/package.json b/package.json index d482a79..0c2577f 100644 --- a/package.json +++ b/package.json @@ -31,10 +31,10 @@ "async": "2.6.4", "debug": "^2.6.0", "underscore": "^1.8.0", - "xml-crypto": "^2.0.0", + "xml-crypto": "2.1.5", "xml-encryption": "2.0.0", "xml2js": "^0.4.0", "xmlbuilder": "~2.2.0", - "xmldom": "^0.6.0" + "@xmldom/xmldom": "0.7.7" } } diff --git a/test/saml2.coffee b/test/saml2.coffee index 4c7e4a4..bb64a64 100644 --- a/test/saml2.coffee +++ b/test/saml2.coffee @@ -7,7 +7,7 @@ fs = require 'fs' saml2 = require "#{__dirname}/../index" url = require 'url' util = require 'util' -xmldom = require 'xmldom' +xmldom = require '@xmldom/xmldom' xmlcrypto = require 'xml-crypto' describe 'saml2', -> From 7853377bcb6e603258cb065ac628f782a519ab14 Mon Sep 17 00:00:00 2001 From: Tsvetomir Nedyalkov Date: Thu, 9 Feb 2023 16:24:32 +0200 Subject: [PATCH 11/11] Bumped version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index d515f3a..fc25532 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@progresskinvey/saml2-js", - "version": "2.3.0", + "version": "2.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 0c2577f..f54abe7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@progresskinvey/saml2-js", - "version": "2.3.0", + "version": "2.3.1", "description": "SAML 2.0 node helpers", "author": "Clever", "main": "index.js",