From b16106830572fb303ac0bf82ed2f16282a465d60 Mon Sep 17 00:00:00 2001 From: Stavros Soleas Date: Fri, 12 Oct 2018 18:33:43 +0300 Subject: [PATCH] Validate issuer on logout requests/responses if configured --- README.md | 2 ++ lib/passport-saml/saml.js | 14 ++++++++------ test/tests.js | 12 ++++++------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cb60382e..0747d024 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,8 @@ type Profile = { * `validateInResponseTo`: if truthy, then InResponseTo will be validated from incoming SAML responses * `requestIdExpirationPeriodMs`: Defines the expiration time when a Request ID generated for a SAML request will not be valid if seen in a SAML response in the `InResponseTo` field. Default is 8 hours. * `cacheProvider`: Defines the implementation for a cache provider used to store request Ids generated in SAML requests as part of `InResponseTo` validation. Default is a built-in in-memory cache provider. For details see the 'Cache Provider' section. + * **Issuer Validation** + * `idpIssuer`: if provided, then the IdP issuer will be validated for incoming Logout Requests/Responses. For ADFS this looks like `https://acme_tools.windows.net/deadbeef` * **Passport** * `passReqToCallback`: if truthy, `req` will be passed as the first argument to the verify callback (default: `false`) * `name`: Optionally, provide a custom name. (default: `saml`). Useful If you want to instantiate the strategy multiple times with different configurations, diff --git a/lib/passport-saml/saml.js b/lib/passport-saml/saml.js index ed1e56e0..a231238d 100644 --- a/lib/passport-saml/saml.js +++ b/lib/passport-saml/saml.js @@ -845,12 +845,14 @@ SAML.prototype.verifyLogoutResponse = function (doc) { }; SAML.prototype.verifyIssuer = function (samlMessage) { - var issuer = samlMessage.Issuer; - if (issuer && this.options.samlIssuer) { - if (issuer[0] !== this.options.samlIssuer && issuer[0]._ !== this.options.samlIssuer) - throw 'Unknown SAML issuer. Expected: ' + this.options.samlIssuer + ' Received: ' + issuer[0]; - } else { - throw 'Missing SAML issuer'; + if(this.options.idpIssuer) { + var issuer = samlMessage.Issuer; + if (issuer) { + if (issuer[0] !== this.options.idpIssuer && issuer[0]._ !== this.options.idpIssuer) + throw 'Unknown SAML issuer. Expected: ' + this.options.idpIssuer + ' Received: ' + issuer[0]; + } else { + throw 'Missing SAML issuer'; + } } }; diff --git a/test/tests.js b/test/tests.js index 18a62e94..f6fe1896 100644 --- a/test/tests.js +++ b/test/tests.js @@ -1877,7 +1877,7 @@ describe( 'passport-saml /', function() { beforeEach(function() { samlObj = new SAML({ cert: fs.readFileSync(__dirname + '/static/acme_tools_com.cert', 'ascii'), - samlIssuer: 'http://localhost:20000/saml2/idp/metadata.php' + idpIssuer: 'http://localhost:20000/saml2/idp/metadata.php' }); this.request = Object.assign({}, require('./static/idp_slo_redirect')); this.clock = sinon.useFakeTimers(Date.parse('2018-04-11T14:08:00Z')); @@ -1894,8 +1894,8 @@ describe( 'passport-saml /', function() { done(); }); }); - it('errors if samlIssuer is set and issuer is wrong', function(done) { - samlObj.options.samlIssuer = 'foo'; + it('errors if idpIssuer is set and issuer is wrong', function(done) { + samlObj.options.idpIssuer = 'foo'; samlObj.validateRedirect(this.request, function(err) { should.exist(err); err.should.eql( @@ -1939,7 +1939,7 @@ describe( 'passport-saml /', function() { beforeEach(function() { samlObj = new SAML({ cert: fs.readFileSync(__dirname + '/static/acme_tools_com.cert', 'ascii'), - samlIssuer: 'http://localhost:20000/saml2/idp/metadata.php', + idpIssuer: 'http://localhost:20000/saml2/idp/metadata.php', validateInResponseTo: true }); this.request = Object.assign({}, require('./static/sp_slo_redirect')); @@ -1958,8 +1958,8 @@ describe( 'passport-saml /', function() { done(); }); }); - it('errors if samlIssuer is set and wrong issuer', function(done) { - samlObj.options.samlIssuer = 'foo'; + it('errors if idpIssuer is set and wrong issuer', function(done) { + samlObj.options.idpIssuer = 'foo'; samlObj.validateRedirect(this.request, function(err) { should.exist(err); err.should.eql(