diff --git a/README.md b/README.md index ceda12d..861e1df 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,11 @@ Options | jwtAlgorithm| If using JWT signed assertion, indicates the algorithm to be applied | RS256 | jwtAllowInsecureKeySizes| Insecure and not recommended, for backward compatibility ONLY. If true, allows insecure key sizes to be used when signing with JWT| false | jwtAllowInvalidAsymmetricKeyTypes| Insecure and not recommended, for backward compatibility ONLY. If true, allows a mismatch between JWT algorithm and the actual key type provided to sign. | false +| encryptionPublicKey | Public key used to encrypt the SAML assertion | +| encryptionCert | Certificate used to encrypt SAML assertion | +| encryptionAlgorithm | The encryption algorithm to encrypt saml assertion | http://www.w3.org/2009/xmlenc11#aes256-gcm ( [node-xml-encryption](https://github.com/auth0/node-xml-encryption/blob/master/README.md) details the available encryption algorithms and configuration options.) +| disallowEncryptionWithInsecureAlgorithm | If true, disallows encryption with algorithms considered insecure by [node-xml-encryption](https://github.com/auth0/node-xml-encryption/blob/master/README.md) | true +| warnOnInsecureEncryptionAlgorithm | If true, logs a warning when using an insecure encryption algorithm | true Add the middleware as follows: diff --git a/lib/wsfed.js b/lib/wsfed.js index 17c15f3..f246226 100644 --- a/lib/wsfed.js +++ b/lib/wsfed.js @@ -39,6 +39,9 @@ function asResource(res) { * @param {boolean} options.jwtAllowInsecureKeySizes Insecure and not recommended, for backward compatibility ONLY. If true, allows insecure key sizes to be used when signing with JWT. Default false. * @param {boolean} options.jwtAllowInvalidAsymmetricKeyTypes Insecure and not recommended, for backward compatibility ONLY. * If true, allows a mismatch between JWT algorithm and the actual key type provided to sign. + * @param {boolean} options.encryptionAlgorithm encryption algorithm to encrypt the assertion. default http://www.w3.org/2009/xmlenc11#aes256-gcm + * @param {boolean} options.disallowEncryptionWithInsecureAlgorithm if true, disallows encryption with algorithms considered insecure. default true. + * @param {boolean} options.warnOnInsecureEncryptionAlgorithm if true, logs a warning when using an insecure encryption algorithm. default true. * * @return {function} An Express middleware that acts as a WsFed endpoint. */ @@ -95,18 +98,21 @@ module.exports = function(options) { } saml11.create({ - signatureAlgorithm: options.signatureAlgorithm, - digestAlgorithm: options.digestAlgorithm, - cert: options.cert, - key: options.key, - issuer: asResource(options.issuer), - lifetimeInSeconds: options.lifetime || options.lifetimeInSeconds || (60 * 60 * 8), - audiences: audience, - attributes: claims, - nameIdentifier: ni.nameIdentifier, - nameIdentifierFormat: ni.nameIdentifierFormat || options.nameIdentifierFormat, - encryptionPublicKey: options.encryptionPublicKey, - encryptionCert: options.encryptionCert + signatureAlgorithm: options.signatureAlgorithm, + digestAlgorithm: options.digestAlgorithm, + cert: options.cert, + key: options.key, + issuer: asResource(options.issuer), + lifetimeInSeconds: options.lifetime || options.lifetimeInSeconds || (60 * 60 * 8), + audiences: audience, + attributes: claims, + nameIdentifier: ni.nameIdentifier, + nameIdentifierFormat: ni.nameIdentifierFormat || options.nameIdentifierFormat, + encryptionPublicKey: options.encryptionPublicKey, + encryptionCert: options.encryptionCert, + encryptionAlgorithm: options.encryptionAlgorithm, + disallowEncryptionWithInsecureAlgorithm: options.disallowEncryptionWithInsecureAlgorithm, + warnOnInsecureEncryptionAlgorithm: options.warnOnInsecureEncryptionAlgorithm }, function(err, assertion) { if (err) return next(err); var escapedWctx = utils.escape(ctx); diff --git a/package.json b/package.json index d4ca471..896dba1 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@auth0/thumbprint": "0.0.6", "ejs": "^3.1.10", "jsonwebtoken": "^9.0.0", - "saml": "^3.0.1", + "saml": "^4.0.0", "xtend": "~2.0.3" }, "devDependencies": { @@ -45,7 +45,7 @@ "request": "~2.88.2", "semantic-release": "^25.0.2", "xml-crypto": "~0.10.1", - "xml-encryption": "1.2.1", + "xml-encryption": "^4.0.0", "xmldom": "~0.1.17", "xpath": "0.0.5" } diff --git a/test/wsfed-encryption.tests.js b/test/wsfed-encryption.tests.js index 077ebe9..ff6d30e 100644 --- a/test/wsfed-encryption.tests.js +++ b/test/wsfed-encryption.tests.js @@ -77,5 +77,98 @@ describe('when dwdw encrypting the assertion', function () { }); }); }); + + describe('with aes256-cbc encryption algorithm', function () { + var statusCode, body; + + before(function (done) { + server.options.encryptionAlgorithm = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'; + request.get({ + jar: request.jar(), + uri: 'http://localhost:5050/wsfed?wa=wsignin1.0&wctx=123&wtrealm=urn:the-super-client-id' + }, function (err, response, b){ + if(err) return done(err); + statusCode = response.statusCode; + body = b; + done(); + }); + }); + + it('should response with 400 status code and insecure algorithm error message', function(){ + expect(statusCode).to.equal(400); + expect(body).to.equal('encryption algorithm http://www.w3.org/2001/04/xmlenc#aes256-cbc is not secure'); + }); + + }); + + describe('with aes256-gcm encryption algorithm', function () { + var statusCode; + + before(function (done) { + server.options.encryptionAlgorithm = 'http://www.w3.org/2009/xmlenc11#aes256-gcm'; + request.get({ + jar: request.jar(), + uri: 'http://localhost:5050/wsfed?wa=wsignin1.0&wctx=123&wtrealm=urn:the-super-client-id' + }, function (err, response, body){ + if(err) return done(err); + statusCode = response.statusCode; + done(); + }); + }); + + it('should response with 200 status code', function(){ + expect(statusCode).to.equal(200); + }); + + }); + + describe('with aes256-cbc encryption algorithm and disallowEncryptionWithInsecureAlgorithm set to true', function () { + var statusCode, body; + + before(function (done) { + server.options.encryptionAlgorithm = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'; + server.options.disallowEncryptionWithInsecureAlgorithm = true; + server.options.warnOnInsecureEncryptionAlgorithm = false; + request.get({ + jar: request.jar(), + uri: 'http://localhost:5050/wsfed?wa=wsignin1.0&wctx=123&wtrealm=urn:the-super-client-id' + }, function (err, response, b){ + if(err) return done(err); + statusCode = response.statusCode; + body = b; + done(); + }); + }); + + it('should response with 400 error', function(){ + expect(statusCode).to.equal(400); + expect(body).to.equal('encryption algorithm http://www.w3.org/2001/04/xmlenc#aes256-cbc is not secure'); + }); + + }); + + describe('with aes256-cbc encryption algorithm and disallowEncryptionWithInsecureAlgorithm set to false', function () { + var statusCode; + + before(function (done) { + server.options.encryptionAlgorithm = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'; + server.options.disallowEncryptionWithInsecureAlgorithm = false; + server.options.warnOnInsecureEncryptionAlgorithm = true; + request.get({ + jar: request.jar(), + uri: 'http://localhost:5050/wsfed?wa=wsignin1.0&wctx=123&wtrealm=urn:the-super-client-id' + }, function (err, response, body){ + if(err) return done(err); + statusCode = response.statusCode; + done(); + }); + }); + + it('should response with 200 status code', function(){ + expect(statusCode).to.equal(200); + }); + + }); -}); \ No newline at end of file +}); +