* Removes commands from old defaults that could execute arbitrary code * This addresses the security vulnerability where npm install/test can run malicious postinstall scripts
( context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel, )
| 122 | * This addresses the security vulnerability where npm install/test can run malicious postinstall scripts |
| 123 | */ |
| 124 | async function migrateDefaultCommands( |
| 125 | context: vscode.ExtensionContext, |
| 126 | outputChannel: vscode.OutputChannel, |
| 127 | ): Promise<void> { |
| 128 | try { |
| 129 | // Check if this migration has already been run |
| 130 | const migrationKey = "defaultCommandsMigrationCompleted" |
| 131 | if (context.globalState.get(migrationKey)) { |
| 132 | outputChannel.appendLine("[Default Commands Migration] Migration already completed, skipping") |
| 133 | return |
| 134 | } |
| 135 | |
| 136 | const allowedCommands = context.globalState.get<string[]>("allowedCommands") |
| 137 | |
| 138 | if (!allowedCommands || !Array.isArray(allowedCommands)) { |
| 139 | // Mark migration as complete even if no commands to migrate |
| 140 | await context.globalState.update(migrationKey, true) |
| 141 | outputChannel.appendLine("No allowed commands found in global state, marking migration as complete") |
| 142 | return |
| 143 | } |
| 144 | |
| 145 | // Only migrate the specific commands that were removed from the defaults |
| 146 | const oldDefaultCommands = ["npm install", "npm test", "tsc"] |
| 147 | |
| 148 | // Filter out old default commands (case-insensitive exact match only) |
| 149 | const originalLength = allowedCommands.length |
| 150 | const filteredCommands = allowedCommands.filter((cmd) => { |
| 151 | const cmdLower = cmd.toLowerCase().trim() |
| 152 | return !oldDefaultCommands.some((oldDefault) => cmdLower === oldDefault.toLowerCase()) |
| 153 | }) |
| 154 | |
| 155 | if (filteredCommands.length < originalLength) { |
| 156 | const removedCount = originalLength - filteredCommands.length |
| 157 | await context.globalState.update("allowedCommands", filteredCommands) |
| 158 | |
| 159 | outputChannel.appendLine( |
| 160 | `[Default Commands Migration] Removed ${removedCount} command(s) from old defaults to prevent arbitrary code execution vulnerability`, |
| 161 | ) |
| 162 | } else { |
| 163 | outputChannel.appendLine("[Default Commands Migration] No old default commands found in allowed list") |
| 164 | } |
| 165 | |
| 166 | // Mark migration as complete |
| 167 | await context.globalState.update(migrationKey, true) |
| 168 | outputChannel.appendLine("[Default Commands Migration] Migration marked as complete") |
| 169 | } catch (error) { |
| 170 | outputChannel.appendLine(`[Default Commands Migration] Error migrating default commands: ${error}`) |
| 171 | } |
| 172 | } |
no test coverage detected