@@ -9,6 +9,15 @@ const fs = require('fs')
99const parseArgs = require ( 'yargs-parser' )
1010const cloneDeep = require ( 'lodash.clonedeep' )
1111
12+ // Forbidden key paths, for protection against prototype pollution
13+ const FORBIDDEN_KEY_PATHS = [
14+ '__proto__' ,
15+ 'this.constructor.prototype' ,
16+ ]
17+
18+ const ALLOWED_OPTION_STRICT = 'strict'
19+ const ALLOWED_OPTION_WARN = 'warn'
20+
1221function assert ( assertion , err_msg ) {
1322 if ( ! assertion ) {
1423 throw new Error ( err_msg )
@@ -69,9 +78,6 @@ const custom_converters = new Map()
6978
7079const parsers_registry = { '*' : JSON . parse }
7180
72- const ALLOWED_OPTION_STRICT = 'strict'
73- const ALLOWED_OPTION_WARN = 'warn'
74-
7581function flatten ( obj , useProperties ) {
7682 const stack = Object . keys ( obj )
7783 let key
@@ -561,14 +567,18 @@ const convict = function convict(def, opts) {
561567 * exist, they will be initialized to empty objects
562568 */
563569 set : function ( k , v ) {
570+ for ( const path of FORBIDDEN_KEY_PATHS ) {
571+ if ( k . startsWith ( `${ path } .` ) ) {
572+ return this
573+ }
574+ }
575+
564576 v = coerce ( k , v , this . _schema , this )
565577 const path = k . split ( '.' )
566578 const childKey = path . pop ( )
567579 const parentKey = path . join ( '.' )
568- if ( ! ( parentKey == '__proto__' || parentKey == 'constructor' || parentKey == 'prototype' ) ) {
569- const parent = walk ( this . _instance , parentKey , true )
570- parent [ childKey ] = v
571- }
580+ const parent = walk ( this . _instance , parentKey , true )
581+ parent [ childKey ] = v
572582 return this
573583 } ,
574584
0 commit comments