VYPR
Critical severityCISA KEVNVD Advisory· Published Dec 24, 2019· Updated Oct 21, 2025

CVE-2019-10758

CVE-2019-10758

Description

mongo-express before 0.54.0 is vulnerable to Remote Code Execution via endpoints that uses the toBSON method. A misuse of the vm dependency to perform exec commands in a non-safe environment.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
mongo-expressnpm
< 0.54.00.54.0

Affected products

1
  • mongo-express/mongo-expressdescription

Patches

2
7d365141dead

Bump 0.54

https://github.com/mongo-express/mongo-expressHugo DozoisDec 24, 2019via ghsa
3 files changed · +748 3
  • HISTORY.md+23 0 modified
    @@ -1,3 +1,26 @@
    +# 0.54 - Tue Dec 24, 2019
    +
    +Breaking:
    +- Change bson parsing to use mongo-query-parser [(#522)](https://github.com/mongo-express/mongo-express/pull/#522)
    +- Drop support for node 6
    +
    +New:
    +- Support playing .wav file inline in collection [(#508)](https://github.com/mongo-express/mongo-express/pull/508)
    +- Add node 12, and 13 to CI [(#517)](https://github.com/mongo-express/mongo-express/pull/517)
    +- Add yarn.lock [(#515)](https://github.com/mongo-express/mongo-express/pull/515)
    +- Fix broken save document for UUID (BinData 3 & 4) [(#537)](https://github.com/mongo-express/mongo-express/pull/#537)
    +
    +Deps:
    +- Pin Event stream to 4.0 [(#514)](https://github.com/mongo-express/mongo-express/pull/514)
    +- Bump bootstrap from 3.3.7 to 3.4.1 [(#523)](https://github.com/mongo-express/mongo-express/pull/#523)
    +- Bump lodash from 4.17.11 to 4.17.13 [(#532)](https://github.com/mongo-express/mongo-express/pull/#532)
    +- Bump jquery from 3.3.1 to 3.4.1 [(#530)](https://github.com/mongo-express/mongo-express/pull/#530)
    +- Bump mixin-deep from 1.3.1 to 1.3.2 [(#526)](https://github.com/mongo-express/mongo-express/pull/#526)
    +- Bump js-yaml from 3.12.0 to 3.13.1 [(#527)](https://github.com/mongo-express/mongo-express/pull/#527)
    +- Bump cross-env from 3.2.4 to 6.0.3 [(#519)](https://github.com/mongo-express/mongo-express/pull/#519)
    +- Bump concurrently from 3.6.1 to 5.0.0 [(#507)](https://github.com/mongo-express/mongo-express/pull/#507)
    +
    +
     # 0.53 - Sat Jul 20, 2019
     New:
     - Add support to read CA certificate from file [(#465)](https://github.com/mongo-express/mongo-express/pull/465)
    
  • package.json+1 1 modified
    @@ -1,5 +1,5 @@
     {
    -  "version": "0.53.0",
    +  "version": "0.54.0",
       "author": "https://github.com/mongo-express",
       "name": "mongo-express",
       "description": "Web-based admin interface for MongoDB",
    
  • yarn.lock+724 2 modified
d8c9bda46a20

Change bson parsing to use mongo-query-parser

https://github.com/mongo-express/mongo-expressHugo DozoisNov 11, 2019via ghsa
6 files changed · +123 477
  • lib/bson.js+10 101 modified
    @@ -1,65 +1,11 @@
     'use strict';
     
    -var mongodb = require('mongodb');
    -var vm      = require('vm');
    -var json    = require('./json');
    +const parser = require('mongodb-query-parser');
    +const ESJON = require('mongodb-extended-json');
    +const mongodb = require('mongodb');
     
    -//Adaptors for BSON types
    -
    -var DBRef = function (namespace, oid, db) {
    -  //Allow empty/undefined db value
    -  if (db === undefined || db === null) {
    -    db = '';
    -  }
    -
    -  var objectId = exports.toObjectId(oid);
    -  if (objectId === false) {
    -    objectId = mongodb.ObjectId(oid);
    -  }
    -  return mongodb.DBRef(namespace, objectId, db);
    -};
    -
    -var Timestamp = function (high, low) {
    -  //Switch low/high bits to Timestamp constructor
    -  return mongodb.Timestamp(low, high);
    -};
    -
    -//Create sandbox with BSON data types
    -exports.getSandbox = function () {
    -  return {
    -    Long: mongodb.Long,
    -    NumberLong: mongodb.Long,
    -    Double: mongodb.Double,
    -    NumberDouble: mongodb.Double,
    -    ObjectId: mongodb.ObjectID,
    -    ObjectID: mongodb.ObjectID,
    -    Timestamp: Timestamp,
    -    DBRef: DBRef,
    -    Dbref: DBRef,
    -    Binary: mongodb.Binary,
    -    BinData: mongodb.Binary,
    -    Code: mongodb.Code,
    -    Symbol: mongodb.Symbol,
    -    MinKey: mongodb.MinKey,
    -    MaxKey: mongodb.MaxKey,
    -    ISODate: Date,
    -    Date: Date,
    -    Buffer: Buffer,
    -  };
    -};
    -
    -//JSON.parse doesn't support BSON data types
    -//Document is evaluated in a vm in order to support BSON data types
    -//Sandbox contains BSON data type functions from node-mongodb-native
     exports.toBSON = function (string) {
    -  var sandbox = exports.getSandbox();
    -
    -  string = string.replace(/ISODate\(/g, 'new ISODate(');
    -  string = string.replace(/Binary\(("[^"]+"),/g, 'Binary(new Buffer($1, "base64"),');
    -
    -  vm.runInNewContext('doc = eval((' + string + '));', sandbox);
    -
    -  return sandbox.doc;
    +  return parser(string);
     };
     
     // This function as the name suggests attempts to parse
    @@ -74,55 +20,18 @@ exports.toSafeBSON = function (string) {
       }
     };
     
    -// Converts string to ObjectID.
    -exports.toObjectId = function (string) {
    -  var sandbox = exports.getSandbox();
    -
    -  // Validation
    -  if (
    -    !string ||                                            // No input at all
    -    string === '' ||                                      // empty string
    -    string.toUpperCase().indexOf('OBJECTID(') === -1 ||   // missing the opening 'ObjectID('
    -    string.indexOf(')') === -1                            // missing the closing '('
    -  ) {
    -    return false;
    -  }
    -
    -  // Strip quotes
    -  string = string.replace('"', '').replace('"', '');
    -
    -  // Convert ObjectId("526ddf5a9f610ffd26000001") to 526ddf5a9f610ffd26000001
    -  string = string.replace(/ObjectID\(/i, '').replace(')', '');
    -
    -  // Make sure it's a 24-character string to prevent errors.
    -  if (string.length === 24) {
    -    return sandbox.ObjectID(string);
    -  } else {
    -    return false;
    -  }
    -};
    -
    -// Convert 24-digit hex string to ObjectId
    -exports.hexToObjectId = function (string) {
    -  if (!/^[0-9a-f]{24}$/.test(string)) {
    -    return false;
    +exports.parseObjectId = function (string) {
    +  if (/^[0-9a-f]{24}$/i.test(string)) {
    +    return mongodb.ObjectId(string);
       }
    -  var sandbox = exports.getSandbox();
    -  return sandbox.ObjectID(string);
    +  return exports.toBSON(string);
     };
     
     //Convert BSON documents to string
     exports.toString = function (doc) {
    -  //Use custom json stringify function from json.js
    -  return json.stringify(doc, null, '    ');
    +  return parser.toJSString(doc, '    ');
     };
     
     exports.toJsonString = function (doc) {
    -  let sJson = json.stringify(doc, null);
    -  sJson = sJson.replace(/ObjectID\(([^)]+)\)/g, '{ "$oid": $1 }');
    -  sJson = sJson.replace(/([-])?Infinity/g, '"$1Infinity"');
    -  sJson = sJson.replace(/NaN/g, '"NaN"');
    -  sJson = sJson.replace(/DBRef\(([^)]+)\)/g, '{ "$ref": $1 }');
    -  sJson = sJson.replace(/ISODate\(([^)]+)\)/g, '$1');
    -  return sJson;
    +  return ESJON.stringify(doc);
     };
    
  • lib/json.js+0 271 removed
    @@ -1,271 +0,0 @@
    -'use strict';
    -
    -var mongodb = require('mongodb');
    -
    -//Original code from official JSON.stringify function
    -//Modified to accept BSON data types
    -
    -/*exported f */
    -// function f(n) {
    -//   // Format integers to have at least two digits.
    -//   return n < 10 ? '0' + n : n;
    -// }
    -
    -/*
    -if (typeof Date.prototype.toJSON !== 'function') {
    -
    -    Date.prototype.toJSON = function (key) {
    -
    -        return isFinite(this.valueOf())
    -            ? this.getUTCFullYear()     + '-' +
    -                f(this.getUTCMonth() + 1) + '-' +
    -                f(this.getUTCDate())      + 'T' +
    -                f(this.getUTCHours())     + ':' +
    -                f(this.getUTCMinutes())   + ':' +
    -                f(this.getUTCSeconds())   + 'Z'
    -            : null;
    -    };
    -
    -    String.prototype.toJSON      =
    -        Number.prototype.toJSON  =
    -        Boolean.prototype.toJSON = function (key) {
    -            return this.valueOf();
    -        };
    -}
    -*/
    -
    -/*exported cx */
    -// var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
    -// eslint-disable-next-line
    -var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
    -var gap;
    -var indent;
    -var meta = {    // table of character substitutions
    -  '\b': '\\b',
    -  '\t': '\\t',
    -  '\n': '\\n',
    -  '\f': '\\f',
    -  '\r': '\\r',
    -  '"': '\\"',
    -  '\\': '\\\\',
    -};
    -var rep;
    -
    -function quote(string) {
    -
    -  // If the string contains no control characters, no quote characters, and no
    -  // backslash characters, then we can safely slap some quotes around it.
    -  // Otherwise we must also replace the offending characters with safe escape
    -  // sequences.
    -
    -  escapable.lastIndex = 0;
    -  return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
    -    var c = meta[a];
    -    return typeof c === 'string' ?
    -        c :
    -        '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
    -  }) + '"' : '"' + string + '"';
    -}
    -
    -function str(key, holder) {
    -
    -  // Produce a string from holder[key].
    -
    -  var i;          // The loop counter.
    -  var k;          // The member key.
    -  var v;          // The member value.
    -  var length;
    -  var mind = gap;
    -  var partial;
    -  var value = holder[key];
    -
    -  // If the value has a toJSON method, call it to obtain a replacement value.
    -
    -  //Custom code to handle BSON data types
    -  if (value instanceof mongodb.ObjectID) {
    -    return 'ObjectID("' + value + '")';
    -  } else if (value instanceof mongodb.Timestamp) {
    -    return 'Timestamp(' + value.high_ + ', ' + value.low_ + ')';
    -  } else if (value instanceof Date) {
    -    return 'ISODate("' + value.toJSON() + '")';
    -  } else if (value instanceof mongodb.DBRef) {
    -    if (value.db === '') {
    -      return 'DBRef("' + value.namespace + '", "' + value.oid + '")';
    -    } else {
    -      return 'DBRef("' + value.namespace + '", "' + value.oid + '", "' + value.db + '")';
    -    }
    -  } else if (value instanceof mongodb.Code) {
    -    return 'Code("' + value.code + '")';
    -  } else if (value instanceof mongodb.MinKey) {
    -    return 'MinKey()';
    -  } else if (value instanceof mongodb.MaxKey) {
    -    return 'MaxKey()';
    -  } else if (value instanceof mongodb.Symbol) {
    -    return 'Symbol("' + value + '")';
    -  } else if (value instanceof mongodb.Binary) {
    -    return 'Binary("' + value.toJSON(key) + '", ' + value.sub_type +   ')';
    -  }
    -
    -  if (value && typeof value === 'object' &&
    -          typeof value.toJSON === 'function') {
    -    value = value.toJSON(key);
    -  }
    -
    -  // If we were called with a replacer function, then call the replacer to
    -  // obtain a replacement value.
    -
    -  if (typeof rep === 'function') {
    -    value = rep.call(holder, key, value);
    -  }
    -
    -  // What happens next depends on the value's type.
    -  switch (typeof value) {
    -    case 'string':
    -      return quote(value);
    -
    -    case 'number':
    -      // Whatever the value number is:
    -      // * finite
    -      // * NaN
    -      // * +Infinity
    -      // * -Infinity
    -      // let's returning it as string
    -      return String(value);
    -
    -    case 'boolean':
    -    case 'null':
    -
    -      // If the value is a boolean or null, convert it to a string. Note:
    -      // typeof null does not produce 'null'. The case is included here in
    -      // the remote chance that this gets fixed someday.
    -
    -      return String(value);
    -
    -    // If the type is 'object', we might be dealing with an object or an array or
    -    // null.
    -
    -    case 'object':
    -
    -      // Due to a specification blunder in ECMAScript, typeof null is 'object',
    -      // so watch out for that case.
    -
    -      if (!value) {
    -        return 'null';
    -      }
    -
    -      // Make an array to hold the partial results of stringifying this object value.
    -
    -      gap += indent;
    -      partial = [];
    -
    -      // Is the value an array?
    -
    -      if (Object.prototype.toString.apply(value) === '[object Array]') {
    -
    -        // The value is an array. Stringify every element. Use null as a placeholder
    -        // for non-JSON values.
    -
    -        length = value.length;
    -        for (i = 0; i < length; i += 1) {
    -          partial[i] = str(i, value) || 'null';
    -        }
    -
    -        // Join all of the elements together, separated with commas, and wrap them in
    -        // brackets.
    -
    -        v = partial.length === 0 ?
    -            '[]' :
    -            gap ?
    -            '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
    -            '[' + partial.join(',') + ']';
    -        gap = mind;
    -        return v;
    -      }
    -
    -      // If the replacer is an array, use it to select the members to be stringified.
    -
    -      if (rep && typeof rep === 'object') {
    -        length = rep.length;
    -        for (i = 0; i < length; i += 1) {
    -          if (typeof rep[i] === 'string') {
    -            k = rep[i];
    -            v = str(k, value);
    -            if (v) {
    -              partial.push(quote(k) + (gap ? ': ' : ':') + v);
    -            }
    -          }
    -        }
    -      } else {
    -
    -        // Otherwise, iterate through all of the keys in the object.
    -
    -        for (k in value) {
    -          if (Object.prototype.hasOwnProperty.call(value, k)) {
    -            v = str(k, value);
    -            if (v) {
    -              partial.push(quote(k) + (gap ? ': ' : ':') + v);
    -            }
    -          }
    -        }
    -      }
    -
    -      // Join all of the member texts together, separated with commas,
    -      // and wrap them in braces.
    -
    -      v = partial.length === 0 ?
    -          '{}' :
    -          gap ?
    -          '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
    -          '{' + partial.join(',') + '}';
    -      gap = mind;
    -      return v;
    -
    -    default:
    -      console.log('Unexpected Object Type', typeof value, value);
    -      break;
    -  }
    -}
    -
    -// If the JSON object does not yet have a stringify method, give it one.
    -
    -exports.stringify = function (value, replacer, space) {
    -
    -  // The stringify method takes a value and an optional replacer, and an optional
    -  // space parameter, and returns a JSON text. The replacer can be a function
    -  // that can replace values, or an array of strings that will select the keys.
    -  // A default replacer method can be provided. Use of the space parameter can
    -  // produce text that is more easily readable.
    -
    -  var i;
    -  gap = '';
    -  indent = '';
    -
    -  // If the space parameter is a number, make an indent string containing that
    -  // many spaces.
    -
    -  if (typeof space === 'number') {
    -    for (i = 0; i < space; i += 1) {
    -      indent += ' ';
    -    }
    -
    -  // If the space parameter is a string, it will be used as the indent string.
    -
    -  } else if (typeof space === 'string') {
    -    indent = space;
    -  }
    -
    -  // If there is a replacer, it must be a function or an array.
    -  // Otherwise, throw an error.
    -
    -  rep = replacer;
    -  if (replacer && typeof replacer !== 'function' &&
    -          (typeof replacer !== 'object' ||
    -          typeof replacer.length !== 'number')) {
    -    throw new Error('JSON.stringify');
    -  }
    -
    -  // Make a fake root object containing our value under the key of ''.
    -  // Return the result of stringifying the value.
    -
    -  return str('', { '': value });
    -};
    
  • lib/routes/collection.js+1 21 modified
    @@ -51,27 +51,7 @@ var routes = function (config) {
             },
             // If type == O, convert value to ObjectID
             O: function (value) {
    -          // Hex input
    -          var result = bson.hexToObjectId(value);
    -
    -          if (!result) {
    -            // Basic validation
    -            // Check we have ObjectID() wrapper
    -            if (
    -              value.toUpperCase().indexOf('OBJECTID(') === -1 ||   // missing the opening 'ObjectID('
    -              value.indexOf(')') === -1                            // missing the closing '('
    -            ) {
    -              throw new Error('ObjectID(...) wrapper must be present');
    -              // req.session.error = 'ObjectID(...) wrapper must be present';
    -              // return res.redirect('back');
    -            }
    -
    -            result = bson.toObjectId(value);
    -            if (!value) {
    -              throw new Error('ObjectID is invalid');
    -            }
    -          }
    -          return result;
    +          return bson.parseObjectId(value);
             },
             // If type == R, convert to RegExp
             R: function (value) {
    
  • package.json+6 1 modified
    @@ -44,7 +44,10 @@
         "lodash": "~4.17.4",
         "method-override": "^2.3.10",
         "mongodb": "2.2.24",
    +    "mongodb-extended-json": "^1.10",
    +    "mongodb-query-parser": "1.4.3",
         "morgan": "^1.9.0",
    +    "patch-package": "^6.2.0",
         "serve-favicon": "^2.5.0",
         "swig-templates": "2.0.3",
         "update-notifier": "1.0.2"
    @@ -73,14 +76,16 @@
         "webpack": "^2.4.1"
       },
       "resolutions": {
    -    "**/event-stream": "^4.0.1"
    +    "**/event-stream": "^4.0.1",
    +    "bson": "1.1.3"
       },
       "engines": {
         "node": ">=6.0.0",
         "npm": ">=3.0.0"
       },
       "license": "MIT",
       "scripts": {
    +    "postinstall": "patch-package",
         "lint": "eslint .",
         "start": "cross-env NODE_ENV=production node app",
         "start-dev": "concurrently --kill-others \"nodemon app\" \"npm run build-dev\"",
    
  • patches/mongodb-query-parser+1.4.3.patch+19 0 added
    @@ -0,0 +1,19 @@
    +diff --git a/node_modules/mongodb-query-parser/lib/index.js b/node_modules/mongodb-query-parser/lib/index.js
    +index 451a0bb..a550779 100644
    +--- a/node_modules/mongodb-query-parser/lib/index.js
    ++++ b/node_modules/mongodb-query-parser/lib/index.js
    +@@ -41,10 +41,12 @@ const BSON_TO_JS_STRING = {
    +     return `BinData(${subType.toString(16)}, '${v.buffer.toString('base64')}')`;
    +   },
    +   DBRef: function(v) {
    +-    return `DBRef('${v.namespace}', '${v.oid}')`;
    ++    // add db as a param
    ++    return `DBRef('${v.namespace}', '${v.oid}'${typeof v.db === 'string' ? `, '${v.db}'` : ''})`;
    +   },
    +   Timestamp: function(v) {
    +-    return `Timestamp(${v.low}, ${v.high})`;
    ++    // low_ and high_ matches bson 1.X, which is used by this package
    ++    return `Timestamp(${v.low_}, ${v.high_})`;
    +   },
    +   Long: function(v) {
    +     return `NumberLong(${v.toString()})`;
    
  • test/lib/bsonSpec.js+87 83 modified
    @@ -1,16 +1,15 @@
     'use strict';
     
    -var expect = require('chai').expect;
    -var mongodb = require('mongodb');
    +const expect = require('chai').expect;
    +const mongodb = require('mongodb');
     
    -var bson = require('../../lib/bson');
    +const bson = require('../../lib/bson');
     
     describe('BSON', function () {
       describe('toBSON', function () {
         it('should convert documents with native JS types', function () {
    -      var test = '{test: true, "s": "hello", i: -99.44}';
    -      var result = bson.toBSON(test);
    -
    +      const test = '{test: true, "s": "hello", i: -99.44}';
    +      const result = bson.toBSON(test);
           expect(result).to.eql({
             test: true,
             s: 'hello',
    @@ -19,185 +18,174 @@ describe('BSON', function () {
         });
     
         it('should convert ObjectID to BSON', function () {
    -      var test = '{_id: ObjectID(), id2: ObjectId()}';
    -      var result = bson.toBSON(test);
    -
    -      expect(result).to.have.property('_id').to.be.an.instanceof(mongodb.ObjectID);
    -      expect(result).to.have.property('id2').to.be.an.instanceof(mongodb.ObjectID);
    +      const test = '{_id: ObjectID(), id2: ObjectId()}';
    +      const result = bson.toBSON(test);
    +      expect(result).to.have.property('_id').to.be.an.instanceof(mongodb.ObjectId);
    +      expect(result).to.have.property('id2').to.be.an.instanceof(mongodb.ObjectId);
         });
     
         it('should convert ISODate to BSON', function () {
    -      var test = '{date: ISODate(), date2: new Date()}';
    -      var result = bson.toBSON(test);
    +      const test = '{date: ISODate(), date2: new Date()}';
    +      const result = bson.toBSON(test);
     
           expect(result).to.have.property('date').to.be.an.instanceof(Date);
           expect(result).to.have.property('date2').to.be.an.instanceof(Date);
         });
     
         it('should convert Timestamp to BSON', function () {
    -      var test = '{ts: Timestamp()}';
    -      var result = bson.toBSON(test);
    +      const test = '{ts: Timestamp()}';
    +      const result = bson.toBSON(test);
     
           expect(result).to.have.property('ts').to.be.an.instanceof(mongodb.Timestamp);
         });
     
         it('should convert DBRef to BSON', function () {
    -      // eslint-disable-next-line max-len
    -      var test = '{ref: DBRef("coll", "579e18580bddc20700502419"), ref2: DBRef("coll", "579e18580bddc20700502419", "db"), ref3: Dbref("coll", "579e18580bddc20700502419", "")}';
    -      var result = bson.toBSON(test);
    -
    +      const test = `{
    +        ref: DBRef("coll", "579e18580bddc20700502419"),
    +        ref2: DBRef("coll", "579e18580bddc20700502419", "db"),
    +        ref3: DBRef("coll", "579e18580bddc20700502419", "")
    +      }`;
    +      const result = bson.toBSON(test);
           expect(result).to.have.property('ref').to.be.an.instanceof(mongodb.DBRef);
           expect(result).to.have.property('ref').to.have.property('namespace', 'coll');
    -      expect(result).to.have.property('ref').to.have.property('oid').to.be.an.instanceof(mongodb.ObjectID);
    -      expect(result).to.have.property('ref').to.have.property('oid').eql(mongodb.ObjectID('579e18580bddc20700502419'));
    -      expect(result).to.have.property('ref').to.have.property('db', '');
    +      expect(result).to.have.property('ref').to.have.property('oid').eql('579e18580bddc20700502419');
     
           expect(result).to.have.property('ref2').to.be.an.instanceof(mongodb.DBRef);
           expect(result).to.have.property('ref2').to.have.property('db', 'db');
     
           expect(result).to.have.property('ref3').to.be.an.instanceof(mongodb.DBRef);
    +      expect(result).to.have.property('ref3').to.have.property('db', '');
         });
     
         it('should convert Symbol to BSON', function () {
    -      var test = '{symbol: Symbol("test")}';
    -      var result = bson.toBSON(test);
    +      const test = '{symbol: Symbol("test")}';
    +      const result = bson.toBSON(test);
     
           expect(result).to.have.property('symbol').to.be.an.instanceof(mongodb.Symbol);
         });
     
         it('should convert MinKey to BSON', function () {
    -      var test = '{key: MinKey()}';
    -      var result = bson.toBSON(test);
    +      const test = '{key: MinKey()}';
    +      const result = bson.toBSON(test);
     
           expect(result).to.have.property('key').to.be.an.instanceof(mongodb.MinKey);
         });
     
         it('should convert MaxKey to BSON', function () {
    -      var test = '{key: MaxKey()}';
    -      var result = bson.toBSON(test);
    +      const test = '{key: MaxKey()}';
    +      const result = bson.toBSON(test);
     
           expect(result).to.have.property('key').to.be.an.instanceof(mongodb.MaxKey);
         });
     
         it('should convert Code to BSON', function () {
    -      var test = '{code: Code(function() { x; }), code2: Code("function() { x; }")}';
    -      var result = bson.toBSON(test);
    +      const test = '{code: Code(function() { x; }), code2: Code("function() { x; }")}';
    +      const result = bson.toBSON(test);
     
           expect(result).to.have.property('code').to.be.an.instanceof(mongodb.Code);
           expect(result).to.have.property('code2').to.be.an.instanceof(mongodb.Code);
         });
    +
    +    it('should not be executable', function () {
    +      const test = 'this.constructor.constructor("return console")().log(this.constructor.constructor("return process")().mainModule.require(\'child_process\').execSync(\'id\').toString())'; // eslint-disable-line max-len
    +      expect(() => bson.toBSON(test)).throws(/Cannot read property 'constructor' of undefined/);
    +    });
       });
     
       describe('toString', function () {
         it('should convert simple documents', function () {
    -      var test = {
    +      const test = {
             bool: true,
             str: 'string',
             number: -678.53,
    -        list: [
    -          1,
    -          2,
    -          3,
    -        ],
    +        list: [1, 2, 3],
           };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    +      const result = bson.toString(test);
    +      const test2 = bson.toBSON(result);
     
           expect(test).to.eql(test2);
         });
     
         it('should convert ObjectID to string', function () {
    -      var test = {
    -        id: mongodb.ObjectID(),
    -        id2: mongodb.ObjectID('4fb1299686a989240b000001'),
    +      const test = {
    +        id: mongodb.ObjectId(),
    +        id2: mongodb.ObjectId('4fb1299686a989240b000001'),
           };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    +      const result = bson.toString(test);
    +      const test2 = bson.toBSON(result);
     
           expect(test).to.eql(test2);
         });
     
         it('should convert ISODate to string', function () {
    -      var test = {
    +      const test = {
             date: new Date(),
           };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    +      const result = bson.toString(test);
    +      const test2 = bson.toBSON(result);
     
           expect(test).to.eql(test2);
         });
     
         it('should convert Timestamp to string', function () {
    -      var test = {
    +      const test = {
             ts: mongodb.Timestamp(),
             ts2: mongodb.Timestamp(100, 100),
           };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    -
    -      expect(test).to.eql(test2);
    +      const result = bson.toString(test);
    +      const test2 = bson.toBSON(result);
    +      expect(test2).to.eql(test);
         });
     
         it('should convert DBRef to string', function () {
    -      var test = {
    -        ref: mongodb.DBRef('coll', mongodb.ObjectID('57b80f922128ccef64333288'), ''),
    -        ref2: mongodb.DBRef('coll', mongodb.ObjectID('57b80f922128ccef64333288'), 'db'),
    +      const test = {
    +        ref: mongodb.DBRef('coll', mongodb.ObjectId('57b80f922128ccef64333288'), ''),
    +        ref2: mongodb.DBRef('coll', mongodb.ObjectId('57b80f922128ccef64333288'), 'db'),
           };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    -
    -      expect(test).to.eql(test2);
    +      const result = bson.toString(test);
    +      const expected = `{\n    ref: DBRef('coll', '57b80f922128ccef64333288', ''),\n    ref2: DBRef('coll', '57b80f922128ccef64333288', 'db')\n}`;
    +      expect(result).to.eql(expected);
         });
     
         it('should convert Symbol to string', function () {
    -      var test = { symbol: mongodb.Symbol('test') };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    -
    -      expect(test).to.eql(test2);
    +      const test = { symbol: mongodb.Symbol('test') };
    +      const result = bson.toString(test);
    +      expect(result).to.eql(`{\n    symbol: {\n        _bsontype: 'Symbol',\n        value: 'test'\n    }\n}`);
         });
     
         it('should convert MinKey to string', function () {
    -      var test = { key: mongodb.MinKey() };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    +      const test = { key: mongodb.MinKey() };
    +      const result = bson.toString(test);
    +      const test2 = bson.toBSON(result);
     
           expect(test).to.eql(test2);
         });
     
         it('should convert MaxKey to string', function () {
    -      var test = { key: mongodb.MaxKey() };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    +      const test = { key: mongodb.MaxKey() };
    +      const result = bson.toString(test);
    +      const test2 = bson.toBSON(result);
     
           expect(test).to.eql(test2);
         });
     
         it('should convert Code to string', function () {
    -      var test = {
    -        code: mongodb.Code('function() { x; }'),
    -      };
    -      var result = bson.toString(test);
    -      var test2 = bson.toBSON(result);
    -
    -      expect(test).to.eql(test2);
    +      const test = { code: mongodb.Code('function() { x; }') };
    +      const result = bson.toString(test);
    +      expect(result).to.eql(`{\n    code: Code('function() { x; }')\n}`);
         });
       });
     
       describe('toJsonString', function () {
         it('should convert to a valid JSON string', function () {
           const doc = {
             dateObject: new Date(Date.UTC(2017, 1, 11)),
    -        objectID: new mongodb.ObjectID('589f79826ea20d18e06b1c36'),
    +        objectID: new mongodb.ObjectId('589f79826ea20d18e06b1c36'),
             someValue: 'someValue',
    -        nestedObject: {
    -          level1: {
    -            level2: 2,
    -          },
    -        },
    +        nestedObject: { level1: { level2: 2 } },
           };
           const result = bson.toJsonString(doc);
    -      const expected = '{"dateObject":"2017-02-11T00:00:00.000Z","objectID":{ "$oid": "589f79826ea20d18e06b1c36" },"someValue":"someValue","nestedObject":{"level1":{"level2":2}}}'; // eslint-disable-line max-len
    +      const expected = '{"dateObject":{"$date":"2017-02-11T00:00:00.000Z"},"objectID":{"$oid":"589f79826ea20d18e06b1c36"},"someValue":"someValue","nestedObject":{"level1":{"level2":2}}}'; // eslint-disable-line max-len
           expect(result).to.equal(expected);
           const parsed = JSON.parse(result);
           expect(parsed.someValue).to.equal(doc.someValue);
    @@ -214,4 +202,20 @@ describe('BSON', function () {
           expect(parsed.someString).to.equal(doc.someString);
         });
       });
    +
    +  describe('parseObjectId', function () {
    +    it('should parse a naked id', () => {
    +      const test = '4fb1299686a989240b000001';
    +      const result = bson.parseObjectId(test);
    +      expect(result).to.be.an.instanceof(mongodb.ObjectId);
    +      expect(result.toHexString()).to.equal(test);
    +    });
    +    it('should parse when it has an ObjectId wrapper', () => {
    +      const objectIdStr = '4fb1299686a989240b000001';
    +      const test = `ObjectId("${objectIdStr}")`;
    +      const result = bson.parseObjectId(test);
    +      expect(result).to.be.an.instanceof(mongodb.ObjectId);
    +      expect(result.toHexString()).to.equal(objectIdStr);
    +    });
    +  });
     });
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.