@@ -199,21 +199,45 @@ program
199199
200200program
201201 . command ( 'config-set <key> <value>' )
202- . description ( 'Set a configuration value' )
202+ . description ( 'Set a configuration value (e.g., maxHistorySize, dataDir, gist.enabled) ' )
203203 . action ( ( key , value ) => {
204204 const config = configManager . getConfig ( ) ;
205- const keys = key . split ( '.' ) ;
206205
207- // eslint-disable-next-line @typescript-eslint/no-explicit-any
208- let current : any = config ;
209- for ( let i = 0 ; i < keys . length - 1 ; i ++ ) {
210- if ( ! current [ keys [ i ] ] ) {
211- current [ keys [ i ] ] = { } ;
206+ // Whitelist of allowed config paths to prevent prototype pollution
207+ const allowedPaths = [
208+ 'dataDir' ,
209+ 'maxHistorySize' ,
210+ 'autoSave' ,
211+ 'hotkeys.toggleHistory' ,
212+ 'hotkeys.search' ,
213+ 'gist.enabled' ,
214+ 'gist.token' ,
215+ 'gist.gistId' ,
216+ ] ;
217+
218+ if ( ! allowedPaths . includes ( key ) ) {
219+ console . error (
220+ `Error: Invalid config key. Allowed keys: ${ allowedPaths . join ( ', ' ) } `
221+ ) ;
222+ return ;
223+ }
224+
225+ // Safe key update using whitelist
226+ const keys = key . split ( '.' ) ;
227+ if ( keys . length === 1 ) {
228+ // Top-level key
229+ ( config as any ) [ keys [ 0 ] ] = value ;
230+ } else if ( keys . length === 2 ) {
231+ // Nested key (one level)
232+ if ( ! ( config as any ) [ keys [ 0 ] ] ) {
233+ ( config as any ) [ keys [ 0 ] ] = { } ;
212234 }
213- current = current [ keys [ i ] ] ;
235+ ( config as any ) [ keys [ 0 ] ] [ keys [ 1 ] ] = value ;
236+ } else {
237+ console . error ( 'Error: Config key depth not supported' ) ;
238+ return ;
214239 }
215240
216- current [ keys [ keys . length - 1 ] ] = value ;
217241 configManager . saveConfig ( config ) ;
218242 console . log ( `Set ${ key } = ${ value } ` ) ;
219243 } ) ;
0 commit comments