Skip to content

Commit d7243cd

Browse files
walokraMarko Wallin
authored and
Marko Wallin
committed
Merge branch 'upstream' into upstream_v1.3.5_merge
* upstream: docs: remove badges broken by project rename. bump version to 1.3.5 deps: really bump xml-encryption for node-forge sub-dep upgrade to address vuln. docs: Update package.json / README to reflect site move. deps: bump xml-encryption to address node-forge sub-dep vuln. Update issue templates Update issue templates Bump lodash from 4.17.15 to 4.17.20 (node-saml#449) Bump acorn from 7.1.0 to 7.4.0 (node-saml#448) Return object for XML-valued AttributeValues (node-saml#447) Revert "doc: announce site move." (node-saml#446) doc: announce site move. add yarn-error.log to .gitignore bump version. Fix multi saml strategy race conditions (node-saml#426) v1.3.3 v1.3.2 # Conflicts: # .gitignore # README.md # package.json
2 parents 0e5f766 + e0480e1 commit d7243cd

File tree

10 files changed

+811
-513
lines changed

10 files changed

+811
-513
lines changed

.github/ISSUE_TEMPLATE/bug-report.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: "[BUG]"
5+
labels: bug
6+
assignees: ''
7+
8+
---
9+
10+
<!--
11+
Thanks for submitting a bug report or featureq request to help us improve.
12+
13+
If you have a support question about how to use the module, no one is monitoring the issues
14+
to answer those. Consider posting on StackOverflow instead using the "passport-saml" tag.
15+
-->
16+
17+
** Spec-driven development **
18+
19+
This project is focused on compliance with the SAML 2.0 specification. For any bug report that
20+
involves the SAML spec, please link to the related parts of the spec and quote the passages too.
21+
22+
Start here: http://saml.xml.org/saml-specifications
23+
24+
You might also check the spec to confirm that it doesn't address your particular bug and mention
25+
that you found no references in the spec concerning your issue.
26+
27+
** Community development model **
28+
29+
passport-saml is maintained by a number of current users. There is no author or primary maintainer
30+
waiting to write your tests and documentation for you. To increase the odds that your issue
31+
is promptly dealt with, consider a pull request to address the issue that includes test coverage
32+
and updated documentation.
33+
34+
**To Reproduce**
35+
36+
Steps to reproduce the behavior. Ideally, expressesd through an automated test.
37+
38+
**Expected behavior**
39+
A clear and concise description of what you expected to happen.
40+
41+
**Environment**
42+
- Node.js version:
43+
- passport-saml version:
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: "[ENHANCE]"
5+
labels: enhancement
6+
assignees: ''
7+
8+
---
9+
10+
<!--
11+
Thanks for submitting a bug report or featureq request to help us improve.
12+
13+
If you have a support question about how to use the module, no one is monitoring the issues
14+
to answer those. Consider posting on StackOverflow instead using the "passport-saml" tag.
15+
-->
16+
17+
** Spec-driven development **
18+
19+
This project is focused on compliance with the SAML 2.0 specification. For any bug report that
20+
involves the SAML spec, please link to the related parts of the spec and quote the passages too.
21+
22+
Start here: http://saml.xml.org/saml-specifications
23+
24+
You might also check the spec to confirm that it doesn't address your particular bug and mention
25+
that you found no references in the spec concerning your issue.
26+
27+
** Community development model **
28+
29+
passport-saml is maintained by a number of current users. There is no author or primary maintainer
30+
waiting to write your tests and documentation for you. To increase the odds that your issue
31+
is promptly dealt with, consider a pull request to address the issue that includes test coverage
32+
and updated documentation.
33+
34+
**Is your feature request related to a problem? Please describe.**
35+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
36+
37+
**Describe the solution you'd like**
38+
A clear and concise description of what you want to happen.
39+
40+
**Describe alternatives you've considered**
41+
A clear and concise description of any alternative solutions or features you've considered.

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
node_modules/
22
.tern-port
3+
.idea
4+
yarn-error.log

README.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ The options passed when the `MultiSamlStrategy` is initialized are also passed a
8585
e.g. If you provide an `issuer` on `MultiSamlStrategy`, this will be also a default value for every provider.
8686
You can override these defaults by passing a new value through the `getSamlOptions` function.
8787

88-
Using multiple providers supports `validateInResponseTo`, but all the `InResponse` values are stored on the same Cache. This means, if you're using the default `InMemoryCache`, that all providers have access to it and a provider might get its response validated against another's request. [Issue Report](!https://github.com/bergie/passport-saml/issues/334). To amend this you should provide a different cache provider per SAML provider, through the `getSamlOptions` function.
88+
Using multiple providers supports `validateInResponseTo`, but all the `InResponse` values are stored on the same Cache. This means, if you're using the default `InMemoryCache`, that all providers have access to it and a provider might get its response validated against another's request. [Issue Report](!https://github.com/node-saml/passport-saml/issues/334). To amend this you should provide a different cache provider per SAML provider, through the `getSamlOptions` function.
89+
90+
> :warning: **There's a race condition [bug](https://github.com/node-saml/passport-saml/issues/425) in versions < 1.3.3 which makes it vulnerable to DOS attacks**: Please use > 1.3.3 if you want to use this issue
91+
8992

9093
#### The profile object:
9194

@@ -132,7 +135,7 @@ type Profile = {
132135
* `identifierFormat`: if truthy, name identifier format to request from identity provider (default: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`)
133136
* `acceptedClockSkewMs`: Time in milliseconds of skew that is acceptable between client and server when checking `OnBefore` and `NotOnOrAfter` assertion condition validity timestamps. Setting to `-1` will disable checking these conditions entirely. Default is `0`.
134137
* `attributeConsumingServiceIndex`: optional `AttributeConsumingServiceIndex` attribute to add to AuthnRequest to instruct the IDP which attribute set to attach to the response ([link](http://blog.aniljohn.com/2014/01/data-minimization-front-channel-saml-attribute-requests.html))
135-
* `disableRequestedAuthnContext`: if truthy, do not request a specific authentication context. This is [known to help when authenticating against Active Directory](https://github.com/bergie/passport-saml/issues/226) (AD FS) servers.
138+
* `disableRequestedAuthnContext`: if truthy, do not request a specific authentication context. This is [known to help when authenticating against Active Directory](https://github.com/node-saml/passport-saml/issues/226) (AD FS) servers.
136139
* `authnContext`: if truthy, name identifier format to request auth context (default: `urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport`); array of values is also supported
137140
* `RACComparison`: Requested Authentication Context comparison type. Possible values are 'exact','minimum','maximum','better'. Default is 'exact'.
138141

lib/passport-saml/saml.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ SAML.prototype.processValidlySignedAssertion = function(xml, samlResponseXml, in
12431243
);
12441244

12451245
var attrValueMapper = function(value) {
1246-
return typeof value === 'string' ? value : value._;
1246+
return value._ ? value._ : value;
12471247
};
12481248

12491249
if (attributes) {

multiSamlStrategy.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ MultiSamlStrategy.prototype.authenticate = function (req, options) {
3131
return self.error(err);
3232
}
3333

34-
self._saml = new saml.SAML(Object.assign({}, self._options, samlOptions));
35-
self.constructor.super_.prototype.authenticate.call(self, req, options);
34+
var samlService = new saml.SAML(Object.assign({}, self._options, samlOptions));
35+
var strategy = Object.assign({}, self, {_saml: samlService});
36+
Object.setPrototypeOf(strategy, self);
37+
self.constructor.super_.prototype.authenticate.call(strategy, req, options);
3638
});
3739
};
3840

@@ -44,8 +46,10 @@ MultiSamlStrategy.prototype.logout = function (req, callback) {
4446
return callback(err);
4547
}
4648

47-
self._saml = new saml.SAML(Object.assign({}, self._options, samlOptions));
48-
self.constructor.super_.prototype.logout.call(self, req, callback);
49+
var samlService = new saml.SAML(Object.assign({}, self._options, samlOptions));
50+
var strategy = Object.assign({}, self, {_saml: samlService});
51+
Object.setPrototypeOf(strategy, self);
52+
self.constructor.super_.prototype.logout.call(strategy, req, callback);
4953
});
5054
};
5155

@@ -61,8 +65,10 @@ MultiSamlStrategy.prototype.generateServiceProviderMetadata = function( req, dec
6165
return callback(err);
6266
}
6367

64-
self._saml = new saml.SAML(Object.assign({}, self._options, samlOptions));
65-
return callback(null, self.constructor.super_.prototype.generateServiceProviderMetadata.call(self, decryptionCert, signingCert ));
68+
var samlService = new saml.SAML(Object.assign({}, self._options, samlOptions));
69+
var strategy = Object.assign({}, self, {_saml: samlService});
70+
Object.setPrototypeOf(strategy, self);
71+
return callback(null, self.constructor.super_.prototype.generateServiceProviderMetadata.call(strategy, decryptionCert, signingCert));
6672
});
6773
};
6874

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "suomifi-passport-saml",
3-
"version": "1.3.3-sfi.0",
3+
"version": "1.3.5-sfi.0",
44
"license": "MIT",
55
"keywords": [
66
"saml",
@@ -31,7 +31,7 @@
3131
"passport-strategy": "*",
3232
"q": "^1.5.0",
3333
"xml-crypto": "^1.4.0",
34-
"xml-encryption": "^1.0.0",
34+
"xml-encryption": "1.2.1",
3535
"xml2js": "0.4.x",
3636
"xmlbuilder": "^11.0.0",
3737
"xmldom": "0.1.x"

test/multiSamlStrategy.js

+14-6
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ describe('strategy#authenticate', function() {
6868
});
6969

7070
it('uses given options to setup internal saml provider', function(done) {
71+
var superAuthenticateStub = this.superAuthenticateStub;
7172
var samlOptions = {
7273
issuer: 'http://foo.issuer',
7374
callbackUrl: 'http://foo.callback',
@@ -84,7 +85,9 @@ describe('strategy#authenticate', function() {
8485
function getSamlOptions (req, fn) {
8586
try {
8687
fn(null, samlOptions);
87-
strategy._saml.options.should.containEql(Object.assign({},
88+
sinon.assert.calledOnce(superAuthenticateStub)
89+
superAuthenticateStub.calledWith(Object.assign(
90+
{},
8891
{ cacheProvider: 'mock cache provider' },
8992
samlOptions
9093
));
@@ -104,19 +107,19 @@ describe('strategy#authenticate', function() {
104107

105108
describe('strategy#logout', function() {
106109
beforeEach(function() {
107-
this.superAuthenticateStub = sinon.stub(SamlStrategy.prototype, 'logout');
110+
this.superLogoutMock = sinon.stub(SamlStrategy.prototype, 'logout');
108111
});
109112

110113
afterEach(function() {
111-
this.superAuthenticateStub.restore();
114+
this.superLogoutMock.restore();
112115
});
113116

114117
it('calls super with request and auth options', function(done) {
115-
var superAuthenticateStub = this.superAuthenticateStub;
118+
var superLogoutMock = this.superLogoutMock;
116119
function getSamlOptions (req, fn) {
117120
try {
118121
fn();
119-
sinon.assert.calledOnce(superAuthenticateStub);
122+
sinon.assert.calledOnce(superLogoutMock);
120123
done();
121124
} catch (err2) {
122125
done(err2);
@@ -148,6 +151,7 @@ describe('strategy#logout', function() {
148151
});
149152

150153
it('uses given options to setup internal saml provider', function(done) {
154+
var superLogoutMock = this.superLogoutMock;
151155
var samlOptions = {
152156
issuer: 'http://foo.issuer',
153157
callbackUrl: 'http://foo.callback',
@@ -164,7 +168,11 @@ describe('strategy#logout', function() {
164168
function getSamlOptions (req, fn) {
165169
try {
166170
fn(null, samlOptions);
167-
strategy._saml.options.should.containEql(samlOptions);
171+
sinon.assert.calledOnce(superLogoutMock)
172+
superLogoutMock.calledWith(Object.assign(
173+
{},
174+
samlOptions
175+
));
168176
done();
169177
} catch (err2) {
170178
done(err2);

test/tests.js

+34
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,40 @@ describe( 'passport-saml /', function() {
13801380
}
13811381
});
13821382
});
1383+
1384+
it( 'XML AttributeValue should return object', function( done ) {
1385+
const nameid_opaque_string = '*******************************'
1386+
const nameQualifier = 'https://idp.example.org/idp/saml'
1387+
const spNameQualifier = 'https://sp.example.org/sp/entity'
1388+
const format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
1389+
const xml =
1390+
'<Response>' +
1391+
'<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0">' +
1392+
'<saml2:AttributeStatement>' +
1393+
'<saml2:Attribute FriendlyName="eduPersonTargetedID" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">' +
1394+
'<saml2:AttributeValue>' +
1395+
'<saml2:NameID Format="'+format+'" NameQualifier="'+nameQualifier+'" SPNameQualifier="'+spNameQualifier+'">' +
1396+
nameid_opaque_string +
1397+
'</saml2:NameID>' +
1398+
'</saml2:AttributeValue>' +
1399+
'</saml2:Attribute>' +
1400+
'</saml2:AttributeStatement>' +
1401+
'</saml2:Assertion>' +
1402+
'</Response>';
1403+
var base64xml = Buffer.from( xml ).toString('base64');
1404+
var container = { SAMLResponse: base64xml };
1405+
var samlObj = new SAML();
1406+
samlObj.validatePostResponse( container, function( err, profile, logout ) {
1407+
should.not.exist( err );
1408+
const eptid = profile['urn:oid:1.3.6.1.4.1.5923.1.1.1.10'];
1409+
const nameid = eptid['NameID'][0]
1410+
nameid._.should.eql(nameid_opaque_string)
1411+
nameid.$.NameQualifier.should.equal(nameQualifier)
1412+
nameid.$.SPNameQualifier.should.equal(spNameQualifier)
1413+
nameid.$.Format.should.equal(format)
1414+
done();
1415+
});
1416+
});
13831417
});
13841418

13851419

0 commit comments

Comments
 (0)