T09 · Insecure Skill Coding Practices
- Location
scripts/porteden.ps1:92- Finding
Arbitrary PowerShell Command Injection Through Invoke-Expression
- Content
View full analysis
Vulnerability Details
File Location:
scripts/porteden.ps1, lines 92-106
Vulnerability Type: PowerShell command injection
Risk Level: HighVulnerable Code
powershell # 添加剩余参数 if ($RemainingArgs.Count -gt 0 -and $Command.ToLower() -notin @("accounts", "attachments")) { $argsList += $RemainingArgs } try { Write-Host "🔄 正在执行邮件操作..." $fullCommand = "porteden $($argsList -join ' ')" Invoke-Expression $fullCommand if ($LASTEXITCODE -ne 0) { throw "操作失败,退出码:$LASTEXITCODE" } } catch {The same unsafe argument list is also populated from caller-controlled string parameters and unrestricted remaining arguments elsewhere in
scripts/porteden.ps1, including lines 27-29 and 49-87.Technical Analysis
The script accepts arbitrary values through
RemainingArgsand several string parameters, concatenates those values into a single PowerShell command string, and executes the resulting string withInvoke-Expression.Invoke-Expressionparses its input as PowerShell source code rather than passing each value as an opaque process argument. Consequently, an attacker can supply PowerShell metacharacters such as semicolons, pipelines, subexpressions, or embedded quotation marks to terminate the intendedportedencommand and introduce additional commands.The manual quoting used for selected parameters does not provide reliable protection. For example, values are wrapped with escaped double quotes when added to
$argsList, but embedded quotes or PowerShell expressions are not escaped according to a robust command-line encoding scheme.RemainingArgsreceives no validation or escaping at all.Attack Path
- An attacker gains influence over arguments supplied to
porteden.ps1, such as through an agent request, automated workflow, or other caller. - The attacker places PowerShell syntax in a parameter accepted through
RemainingArgsor in one of the ...[truncated 1391 chars]
- An attacker gains influence over arguments supplied to
- Remediation
View remediation
Remediation Suggestions
-
Remove
Invoke-Expressionand never construct a PowerShell source-code string from caller-controlled values. -
Invoke the executable directly and use PowerShell's argument-array handling:
powershell & porteden @argsList $exitCode = $LASTEXITCODE -
Store argument values in
$argsListwithout manually adding quotation-mark characters. Direct invocation passes array elements as arguments and avoids reparsing them as PowerShell code. -
Eliminate unrestricted
ValueFromRemainingArgumentshandling where possible. Define explicit parameters for every supported operation. -
If passthrough arguments are necessary, validate each one against command-specific allowlists of supported flags and expected value formats.
-
Validate numeric ranges, email addresses, dates, profile names, message identifiers, and output paths before invocation.
-
Resolve the expected executable using a trusted absolute path or verify the command source returned by
Get-Commandto reduce executable-path spoofing risks. -
Add security tests containing semicolons, pipelines, embedded quotes, subexpressions, and newline characters, confirming that they are passed only as literal arguments or rejected.
-
