Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredperreault-okta committed Jun 6, 2024
1 parent 84fa6e6 commit 975060f
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 2,966 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# nJwt Change Log

### 2.0.1

* [#107](https://github.com/jwtk/njwt/pull/107) Freeze `prototype` of all classes to prevent prototype pollution vuln ([CVE-2024-34273](https://cve.mitre.org/cgi-bin/cvename.cgi?name=2024-34273))

### 2.0.0

* [#98](https://github.com/jwtk/njwt/pull/98) Bumps jsonwebtoken version, drop Node < 12 from engines
Expand Down
41 changes: 31 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,22 @@ JwtBody.prototype.compact = function compact(){
return base64urlEncode(JSON.stringify(this));
};

function JwtHeader(header){
var reservedHeaderKeys = ['typ','alg'];
function JwtHeader(header, ignoreDefaults){
if(!(this instanceof JwtHeader)){
return new JwtHeader(header);
}
var self = this;
this.typ = header && header.typ || 'JWT';
this.alg = header && header.alg || 'HS256';
this.typ = header && header.typ;
this.alg = header && header.alg;
if (!ignoreDefaults) {
this.typ = this.typ || 'JWT';
this.alg = this.alg || 'HS256';
}

if(header){
return Object.keys(header).reduce(function(acc,key){
if(self.reservedKeys.indexOf(key)===-1 && header.hasOwnProperty(key)){
if(reservedHeaderKeys.indexOf(key)===-1 && header.hasOwnProperty(key)){
acc[key] = header[key];
}
return acc;
Expand All @@ -132,7 +137,6 @@ function JwtHeader(header){
return this;
}
}
JwtHeader.prototype.reservedKeys = ['typ','alg'];
JwtHeader.prototype.compact = function compact(){
return base64urlEncode(JSON.stringify(this));
};
Expand Down Expand Up @@ -312,7 +316,7 @@ Parser.prototype.parse = function parse(jwtString,cb){
jwt.setSigningAlgorithm(header.alg);
jwt.signature = signature;
jwt.verificationInput = segments[0] +'.' + segments[1];
jwt.header = new JwtHeader(header);
jwt.header = new JwtHeader(header, true);
return done(null,jwt);
};

Expand Down Expand Up @@ -409,11 +413,12 @@ Verifier.prototype.verify = function verify(jwtString,cb){

var newJwt = new Jwt(body, false);

newJwt.toString = function () {
return jwtString;
};
// since prototype is now frozen, .toString can no longer be overloaded
// newJwt.toString = function () {
// return jwtString;
// };

newJwt.header = new JwtHeader(header);
newJwt.header = new JwtHeader(header, true);

if (!verified) {
return done(new JwtParseError(properties.errors.SIGNATURE_MISMTACH,jwtString,header,body));
Expand All @@ -428,6 +433,22 @@ Verifier.prototype.withKeyResolver = function withKeyResolver(keyResolver) {
return this;
};

// vuln: https://security.snyk.io/vuln/SNYK-JS-NJWT-6861582
Object.freeze(Jwt);
Object.freeze(Jwt.prototype);
Object.freeze(JwtBody);
Object.freeze(JwtBody.prototype);
Object.freeze(JwtHeader);
Object.freeze(JwtHeader.prototype);
Object.freeze(Verifier);
Object.freeze(Verifier.prototype);
Object.freeze(Parser);
Object.freeze(Parser.prototype);
Object.freeze(JwtParseError);
Object.freeze(JwtParseError.prototype);
Object.freeze(JwtError);
Object.freeze(JwtError.prototype);

var jwtLib = {
Jwt: Jwt,
JwtBody: JwtBody,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "njwt",
"version": "2.0.0",
"version": "2.0.1",
"description": "JWT Library for Node.js",
"engines": {
"node": ">=12.0"
Expand Down
39 changes: 39 additions & 0 deletions test/exports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
var assert = require('chai').assert;
var nJwt = require('..');

describe('njwt module exports',function () {
// https://github.com/chrisandoryan/vuln-advisory/blob/main/nJwt/CVE-2024-34273.md
describe('CVE-2024-34273', function () {
it('should export classes with frozen prototypes', function(){
assert.frozen(nJwt.Jwt);
assert.frozen(nJwt.Jwt.prototype);
assert.frozen(nJwt.JwtBody);
assert.frozen(nJwt.JwtBody.prototype);
assert.frozen(nJwt.JwtHeader);
assert.frozen(nJwt.JwtHeader.prototype);
assert.frozen(nJwt.Verifier);
assert.frozen(nJwt.Verifier.prototype);
});

it('should not allow prototype pollution', function () {

// based on: https://github.com/chrisandoryan/vuln-advisory/blob/main/nJwt/CVE-2024-34273.md#proof-of-concept-poc
var token = `ewogICJ0eXAiOiAiSldUIiwKICAiYWxnIjogIm5vbmUiLAogICJfX3Byb3RvX18iOiB7CiAgICAidHlwIjogIkpXVCIsCiAgICAiYWxnIjogIkhTMjU
2IiwKICAgICJfX3Byb3RvX18iOiB7CiAgICAgICJjb21wYWN0IjogbnVsbCwKICAgICAgInJlc2VydmVkS2V5cyI6IFsKICAgICAgICAidHlwIiwKICAgICAgICAicmF
uZG9tX2dpYmJlcmlzaCIKICAgICAgXQogICAgfQogIH0KfQ.ewogICJzdWIiOiAxLAogICJzY29wZSI6ICJ1c2VyIiwKICAianRpIjogImJhZmIxNmNlLTIwZDYtNGNk
Ny05NDgzLTY1YTA5NThhOGU2NCIsCiAgImlhdCI6IDI1Mzc0Nzg1MDYsCiAgImV4cCI6IDI1Mzc0Nzg1MDYsCiAgIl9fcHJvdG9fXyI6IHsKICAgICJjb21wYWN0Ijog
bnVsbCwKICAgICJ0b0pTT04iOiBudWxsLAogICAgInBvbGx1dGVkIjogdHJ1ZQogIH0KfQ`.replace(/\s/g, '');

assert.isOk(nJwt.JwtBody.prototype.hasOwnProperty('toJSON'))
assert.isOk(nJwt.JwtBody.prototype.hasOwnProperty('compact'))
assert.isOk(nJwt.JwtHeader.prototype.hasOwnProperty('compact'))

nJwt.verify(token);

assert.isOk(nJwt.JwtBody.prototype.hasOwnProperty('toJSON'))
assert.isOk(nJwt.JwtBody.prototype.hasOwnProperty('compact'))
assert.isOk(nJwt.JwtHeader.prototype.hasOwnProperty('compact'))
});
});

});
3 changes: 2 additions & 1 deletion test/verifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ describe('Verifier().setSigningAlgorithm() ',function(){

describe('.verify()',function(){
it('should persist the original token to the toString() invocation',function(){
var token = 'eyJhbGciOiJub25lIn0.eyJzdWIiOiIxMjMifQ.p6bizskaJLAheVyRhQEMR-60PkH_jtLVYgMy1qTjCoc';
// var token = 'eyJhbGciOiJub25lIn0.eyJzdWIiOiIxMjMifQ.p6bizskaJLAheVyRhQEMR-60PkH_jtLVYgMy1qTjCoc';
var token = 'eyJhbGciOiJub25lIn0.eyJzdWIiOiIxMjMifQ';
assert.equal(token,nJwt.verify(token).toString());
});

Expand Down
Loading

0 comments on commit 975060f

Please sign in to comment.