SAML logins are verified by @node-saml/node-saml 5.2.0, as package.json says.

Dependabot's 5.1.0 -> 5.2.0 bump (#6850) changed the app's package.json,
but a SAML login is verified by the wekan-accounts-saml package's own
copy, pinned by its Npm.depends to 5.1.0 - so nothing that runs changed.
5.2.0 is a hardening release a login relies on: it rejects a message
with more than one Issuer, checks idpIssuer on the Response and its
assertion, rejects a parsed query whose RelayState is not the signed
one, and checks a POST LogoutResponse's status and issuer.

The package pins 5.2.0 now. samlLogin.test.cjs required '5.1.0' in one
place and '^5.1.0' in the other; it requires the package and package.json
to name the SAME version, and at least 5.2.0, so a bump of one alone
fails.

A login roundtrip with the package's own copy (node-saml 5.2.0,
xml-crypto 6.4.0) and WeKan's options: a signed Response and a signed
Assertion log in; a NameID changed after signing, a signature by another
key, an unsigned response, and an answer to a request WeKan never made
are refused. saml-popup-error.e2e.js completes a real signed login in
the browser.

Thanks to xet7 !
This commit is contained in:
Lauri Ojansivu committed 2026-10-31 23:06:08 +02:00
1 parent 338afc15f8
commit 5c50f38e25
2 files changed
+14 -3

No files matched your search

+4 -1
View File
@@ -29,7 +29,10 @@ Npm.depends({
// it does not reimplement any SAML/XML-signature handling itself. License
// verified directly from https://github.com/node-saml/node-saml/blob/master/LICENSE
// (MIT, (c) Henri Bergius, Michael Bosworth).
'@node-saml/node-saml': '5.1.0',
// The SAME version as the app's package.json: this copy is the one that
// verifies a login, so a dependency bump of the app's alone (as Dependabot
// makes) changes nothing that runs. tests/samlLogin.test.cjs.
'@node-saml/node-saml': '5.2.0',
// Parses the IdP's application/x-www-form-urlencoded POST to the ACS
// endpoint (saml_server.js's urlEncodedParser). A local Meteor package
// resolves npm dependencies only through its own Npm.depends - it happened
+10 -2
View File
@@ -47,8 +47,16 @@ test('SAML uses the shared environment/Admin Panel resolver and awaited runtime
});
test('the SAML package depends on the verified-MIT @node-saml/node-saml library, not a hand-rolled implementation', () => {
assert.match(samlPackageJs, /'@node-saml\/node-saml':\s*'5\.1\.0'/);
assert.strictEqual(pkgJson.dependencies['@node-saml/node-saml'], '^5.1.0');
// The Meteor package's own copy is the one saml_server.js loads, so it and
// the app's declaration must name the same version. A bump of the app's
// alone - Dependabot's 5.1.0 -> 5.2.0 - left logins verified by 5.1.0.
const pinned = (samlPackageJs.match(/'@node-saml\/node-saml':\s*'([\d.]+)'/) || [])[1];
assert.ok(pinned, 'the package pins an exact version');
assert.strictEqual(pkgJson.dependencies['@node-saml/node-saml'].replace(/^\^/, ''), pinned,
'the package and package.json name the same @node-saml/node-saml');
// 5.2.0: issuer, RelayState and LogoutResponse checks this login relies on.
const [major, minor] = pinned.split('.').map(Number);
assert.ok(major > 5 || (major === 5 && minor >= 2), `at least 5.2.0, not ${pinned}`);
});
test('the server never reimplements XML signature verification itself', () => {