Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove InResponseTo value if response validation fails #341

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lib/passport-saml/saml.js
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,14 @@ SAML.prototype.validatePostResponse = function (container, callback) {
})
.fail(function(err) {
debug('validatePostResponse resulted in an error: %s', err);
callback(err);
if (self.options.validateInResponseTo) {
Q.ninvoke(self.cacheProvider, 'remove', inResponseTo)
.then(function() {
callback(err);
});
} else {
callback(err);
}
})
.done();
};
Expand Down
47 changes: 42 additions & 5 deletions test/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,13 +535,13 @@ describe( 'passport-saml /', function() {
var query = response.headers.location.match( /^[^\?]*\?(.*)$/ )[1];
encodedSamlRequest = querystring.parse( query ).SAMLRequest;
}

var buffer = Buffer.from(encodedSamlRequest, 'base64');
if (check.config.skipRequestCompression)
helper(null, buffer);
else
zlib.inflateRaw( buffer, helper );

function helper(err, samlRequest) {
try {
should.not.exist( err );
Expand Down Expand Up @@ -772,7 +772,7 @@ describe( 'passport-saml /', function() {
try {
var id = doc['samlp:LogoutRequest']['$']["ID"];
var issueInstant = doc['samlp:LogoutRequest']['$']["IssueInstant"];

id.should.be.an.instanceOf(String);
issueInstant.should.be.an.instanceOf(String);
cacheSaveSpy.called.should.eql(true);
Expand Down Expand Up @@ -968,16 +968,52 @@ describe( 'passport-saml /', function() {
should(profile).have.property("evil-corp.egroupid").eql("[email protected]");
// attributes without attributeValue child should be ignored
should(profile).not.have.property("evilcorp.roles");

fakeClock.restore();

done();
} catch (err2) {
done(err2);
}
});
});

it('removes InResponseTo value if response validation fails', function(done) {
var requestId = '_a6fc46be84e1e3cf3c50';
var xml = '<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="R689b0733bccca22a137e3654830312332940b1be" Version="2.0" IssueInstant="2014-05-28T00:16:08Z" Destination="{recipient}" InResponseTo="_a6fc46be84e1e3cf3c50"><saml:Issuer>https://app.onelogin.com/saml/metadata/371755</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>' +
'<saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="2.0" ID="pfx3b63c7be-fe86-62fd-8cb5-16ab6273efaa" IssueInstant="2014-05-28T00:16:08Z"><saml:Issuer>https://app.onelogin.com/saml/metadata/371755</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#pfx3b63c7be-fe86-62fd-8cb5-16ab6273efaa"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>DCnPTQYBb1hKspbe6fg1U3q8xn4=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>e0+aFomA0+JAY0f9tKqzIuqIVSSw7LiFUsneEDKPBWdiTz1sMdgr/2y1e9+rjaS2mRmCi/vSQLY3zTYz0hp6nJNU19+TWoXo9kHQyWT4KkeQL4Xs/gZ/AoKC20iHVKtpPps0IQ0Ml/qRoouSitt6Sf/WDz2LV/pWcH2hx5tv3xSw36hK2NQc7qw7r1mEXnvcjXReYo8rrVf7XHGGxNoRIEICUIi110uvsWemSXf0Z0dyb0FVYOWuSsQMDlzNpheADBifFO4UTfSEhFZvn8kVCGZUIwrbOhZ2d/+YEtgyuTg+qtslgfy4dwd4TvEcfuRzQTazeefprSFyiQckAXOjcw==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>'+TEST_CERT+'</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">[email protected]</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData NotOnOrAfter="2014-05-28T00:19:08Z" Recipient="{recipient}" InResponseTo="_a6fc46be84e1e3cf3c50"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2014-05-28T00:13:08Z" NotOnOrAfter="2014-05-28T00:19:08Z"><saml:AudienceRestriction><saml:Audience>{audience}</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2014-05-28T00:16:07Z" SessionNotOnOrAfter="2014-05-29T00:16:08Z" SessionIndex="_30a4af50-c82b-0131-f8b5-782bcb56fcaa"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>' +
'</samlp:Response>';
var base64xml = Buffer.from( xml ).toString('base64');
var container = { SAMLResponse: base64xml };
var samlConfig = {
entryPoint: 'https://app.onelogin.com/trust/saml2/http-post/sso/371755',
cert: TEST_CERT,
validateInResponseTo: true
};
var samlObj = new SAML( samlConfig );

// Mock the SAML request being passed through Passport-SAML
samlObj.cacheProvider.save(requestId, new Date().toISOString(), function(){});

samlObj.validatePostResponse( container, function( err, profile, logout ) {
try {
should.exist(err);
err.message.should.match("Invalid signature");
} catch (err2) {
done(err2);
}
samlObj.validatePostResponse( container, function( err, profile, logout ) {
try {
should.exist(err);
err.message.should.match("InResponseTo is not valid");
done();
} catch (err2) {
done(err2);
}
});
});
});

describe( 'validatePostResponse xml signature checks /', function() {

var fakeClock;
Expand Down Expand Up @@ -2283,6 +2319,7 @@ describe( 'passport-saml /', function() {
}
});
});

it('returns true for valid signature', function(done) {
samlObj.cacheProvider.save('_79db1e7ad12ca1d63e5b', new Date().toISOString(), function(){});
samlObj.validateRedirect(this.request, function(err, _data, success) {
Expand Down