Uma função do PowerShell precisa executar um .exe cuja localização não é conhecida em tempo de design porque faz parte de um pacote NuGet. Se eu executá-lo usando Invoke-Expression
o PSScriptAnalyzer gera um aviso me dizendo para encontrar um método alternativo, no entanto, se eu executá-lo usando, &
não recebo nenhum aviso.
Esta é a função que faz parte de um módulo para executar testes de unidade e gerar um relatório de cobertura de código em uma máquina onde o IDE instalado não suporta cobertura de código (por exemplo, Visual Studio Community Edition).
function Invoke-ReportGenerator {
param (
[Parameter(Mandatory=$true)][string]$testProjectFolder,
[Parameter(Mandatory=$true)][string]$testProjectName,
[Parameter(Mandatory=$true)][string]$assemblyUnderTest,
[Parameter(Mandatory=$false)][string]$coverageXmlFilename,
[Parameter(Mandatory=$false)][string]$reportGeneratorPath
)
if ([System.String]::IsNullOrWhiteSpace($coverageXmlFilename)) {
$coverageXmlFilename = "coverage.opencover.xml";
}
$absoluteOutputPath = [System.IO.Path]::Combine($testProjectFolder, "CodeCoverage");
$absoluteInputPath = [System.IO.Path]::Combine($testProjectFolder, $coverageXmlFilename);
$argumentArray = @(
"-reports:$absoluteInputPath",
"-targetDir:$absoluteOutputPath",
"-title:$testProjectName",
"-assemblyFilters:$assemblyUnderTest"
);
if ([System.String]::IsNullOrWhiteSpace($reportGeneratorPath)) {
$reportGeneratorPath = "$env:USERPROFILE\.nuget\packages\reportgenerator\5.2.4\tools\net6.0\reportgenerator.exe ";
}
$reportGeneratorCommand = "$reportGeneratorPath $argumentArray";
Invoke-Expression $reportGeneratorCommand;
}
Este é o aviso levantado pelo PSScriptAnalyzer
Invoke-Expression is used. Please remove Invoke-Expression from script and find other options instead.
Os documentos da Microsoft dizem para evitar o uso de Invoke-Expression
Considere cuidadosamente as implicações de segurança. Quando uma string de uma fonte não confiável, como a entrada do usuário, é passada diretamente para Invoke-Expression, comandos arbitrários podem ser executados. Sempre considere primeiro uma solução diferente, mais robusta e segura.
Se eu mudar a linha
Invoke-Expression $reportGeneratorCommand;
para
& $reportGeneratorCommand;
Então o aviso desaparece. Mas certamente isso é tão vulnerável a um ataque de injeção de código quanto Invoke-Expression
? o que estou perdendo?
Editar: substituir as 2 últimas linhas da função pelas & $reportGeneratorPath @argumentArray
sugeridas por @MathiasRJessen simplifica um pouco a função, mas acredito que ainda a deixa vulnerável.