T09 · Insecure Skill Coding Practices
Error
- Location
- references/deploy.md:77
- Finding
- PowerShell Command Injection in Azure Deployment Helper## Vulnerability Details **File Location**: `references/deploy.md`, lines 77–96 **Vulnerability Type**: PowerShell command injection through `Invoke-Expression` **Risk Level**: High ### Vulnerable Code ```powershell # Build the deployment command $deploymentName = "bicep-deploy-$(Get-Date -Format 'yyyyMMdd-HHmmss')" $command = "az deployment group create --resource-group $ResourceGroupName --name $deploymentName --template-file $TemplateFile" if (-not [string]::IsNullOrEmpty($ParametersFile)) { $command += " --parameters @$ParametersFile" } Write-Host "Environment: $Environment" -ForegroundColor Cyan Write-Host "Resource Group: $ResourceGroupName" -ForegroundColor Cyan Write-Host "Template: $TemplateFile" -ForegroundColor Cyan Write-Host "" if ($WhatIf) { Write-Host "Running What-If analysis..." -ForegroundColor Yellow $command = $command -replace "deployment group create", "deployment group what-if" } Write-Host "Executing: $command" -ForegroundColor Gray Write-Host "" # Execute Invoke-Expression $command ``` ### Technical Analysis The script interpolates the user-controlled `$ResourceGroupName`, `$TemplateFile`, and `$ParametersFile` values into a PowerShell command string. It then executes the resulting string with `Invoke-Expression`. `Invoke-Expression` parses its argument as PowerShell source code rather than passing each value to Azure CLI as an isolated argument. Consequently, PowerShell metacharacters contained in any interpolated parameter can terminate or alter the intended Azure CLI command and introduce an additional command. Azure-side resource-name validation does not prevent this issue because PowerShell processes the injected syntax locally before Azure CLI receives its arguments. The vulnerability is reachable in both ordinary deployment and `-WhatIf` modes. ### Attack Path 1. An attacker influences one of the script arguments, such as `ResourceGroupName`, `Tem ...[truncated 1163 chars]
- Remediation
- ## Remediation Suggestions Remove `Invoke-Expression` and invoke Azure CLI using a PowerShell argument array: ```powershell $azArguments = @( "deployment", "group", "create", "--resource-group", $ResourceGroupName, "--name", $deploymentName, "--template-file", $TemplateFile ) if (-not [string]::IsNullOrEmpty($ParametersFile)) { $azArguments += @("--parameters", "@$ParametersFile") } & az @azArguments if ($LASTEXITCODE -ne 0) { throw "Azure deployment failed with exit code $LASTEXITCODE." } ``` For `-WhatIf`, construct a separate argument array rather than performing string replacement. Additionally: - Restrict `$Environment` with `ValidateSet("dev", "staging", "prod")`. - Resolve template and parameter paths with `Resolve-Path`. - Require supported file extensions. - Verify that parameter files exist and are regular files. - Avoid logging values that may contain sensitive deployment parameters. - Run deployments using a least-privileged Azure identity.
