diff --git a/lib/sign-stream.js b/lib/sign-stream.js index e24576f..a7bb2d5 100644 --- a/lib/sign-stream.js +++ b/lib/sign-stream.js @@ -3,13 +3,13 @@ var base64url = require('base64url'); var DataStream = require('./data-stream'); var jwa = require('jwa'); var Stream = require('stream'); -var toString = require('./tostring'); +var toBuffer = require('./to-buffer'); var util = require('util'); function jwsSecuredInput(header, payload, encoding) { encoding = encoding || 'utf8'; - var encodedHeader = base64url(toString(header), 'binary'); - var encodedPayload = base64url(toString(payload), encoding); + var encodedHeader = base64url(toBuffer(header)); + var encodedPayload = base64url(toBuffer(payload, encoding)); return util.format('%s.%s', encodedHeader, encodedPayload); } diff --git a/lib/to-buffer.js b/lib/to-buffer.js new file mode 100644 index 0000000..efb9231 --- /dev/null +++ b/lib/to-buffer.js @@ -0,0 +1,19 @@ +'use strict'; + +var Buffer = require('safe-buffer').Buffer; + +module.exports = function toBuffer(val, encoding) { + if (Buffer.isBuffer(val)) { + return val; + } + if (typeof val === 'string') { + return Buffer.from(val, encoding || 'utf8'); + } + if (typeof val === 'number') { + // This won't work for very large or very small numbers, but is consistent + // with previous behaviour at least + val = val.toString(); + return Buffer.from(val, 'utf8'); + } + return Buffer.from(JSON.stringify(val), 'utf8'); +}; diff --git a/lib/verify-stream.js b/lib/verify-stream.js index d9bfa2b..d815458 100644 --- a/lib/verify-stream.js +++ b/lib/verify-stream.js @@ -68,7 +68,11 @@ function jwsDecode(jwsSig, opts) { var payload = payloadFromJWS(jwsSig); if (header.typ === 'JWT' || opts.json) - payload = JSON.parse(payload, opts.encoding); + try { + payload = JSON.parse(payload, opts.encoding); + } catch(e) { + return null; + } return { header: header, diff --git a/readme.md b/readme.md index e4200b8..a67e532 100644 --- a/readme.md +++ b/readme.md @@ -116,9 +116,9 @@ jws.createSign({ }); // is equivilant to this: -const signer = jws.createSign( +const signer = jws.createSign({ header: { alg: 'RS256' }, -); +}); privateKeyStream.pipe(signer.privateKey); payloadStream.pipe(signer.payload); signer.on('done', function(signature) { diff --git a/test/jws.test.js b/test/jws.test.js index 7f53d6f..da725eb 100644 --- a/test/jws.test.js +++ b/test/jws.test.js @@ -330,3 +330,16 @@ test('jws.isValid', function (t) { t.same(jws.isValid(valid), true); t.end(); }); + +test('#50 mangled binary payload', function(t) { + const sig = jws.sign({ + header: { + alg: 'HS256' + }, + payload: new Buffer('TkJyotZe8NFpgdfnmgINqg==', 'base64'), + secret: new Buffer('8NRxgIkVxP8LyyXSL4b1dg==', 'base64') + }); + + t.same(sig, 'eyJhbGciOiJIUzI1NiJ9.TkJyotZe8NFpgdfnmgINqg.9XilaLN_sXqWFtlUCdAlGI85PCEbJZSIQpakyAle-vo'); + t.end(); +});