Является ли оператор вызова (&) менее уязвимым для атак путем внедрения кода, чем Invoke-Expression?

Функция PowerShell должна запускать EXE-файл, расположение которого неизвестно во время разработки, поскольку он является частью пакета NuGet. Если я запускаю его с помощью Invoke-Expression, PSScriptAnalyzer выдает предупреждение, предлагающее мне найти альтернативный метод, однако если я запускаю его с помощью &, я не получаю предупреждения.

Это функция, которая является частью модуля для запуска модульных тестов и создания отчета о покрытии кода на машине, где установленная IDE не поддерживает покрытие кода (например, 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;
}

Это предупреждение, выданное PSScriptAnalyzer.

Invoke-Expression is used. Please remove Invoke-Expression from script and find other options instead.

В документах Microsoft говорится: Избегайте использования Invoke-Expression

Тщательно рассмотрите последствия для безопасности. Когда строка из ненадежного источника, например ввода пользователя, передается непосредственно в Invoke-Expression, могут выполняться произвольные команды. Всегда сначала рассматривайте другое, более надежное и безопасное решение.

Если я изменю строку

Invoke-Expression $reportGeneratorCommand;

к

& $reportGeneratorCommand;

Затем предупреждение исчезнет. Но ведь он так же уязвим для атаки путем внедрения кода, как и Invoke-Expression? Что мне не хватает?

Обновлено: замена последних двух строк функции на & $reportGeneratorPath @argumentArray, как предложил @MathiasRJessen, немного упрощает функцию, но я считаю, что она все равно остается уязвимой.

Когда я впервые изучал PowerShell, я задал похожий вопрос и получил вот такой ответ.

Darin 27.07.2024 14:54

Вместо этого вы захотите использовать его вот так: & $reportGeneratorPath @argumentArray

Mathias R. Jessen 27.07.2024 14:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
2
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Разница между Invoke-Expression и операторами вызова (& и .) заключается в структурированном синтаксисе.

В отличие от Invoke-Expression, операторы принимают целевую команду и аргументы отдельно, используя следующий синтаксис:

<op> [<module-spec>] <target-command> [arguments...]

... и, как предложено в комментариях, их следует использовать в сочетании со сплаттингом, вот так:

& $command @arguments

но я считаю, что все еще оставляет его уязвимым.

Возможно, следующий пример поколеблет ваши убеждения.

Начнем с определения целевой команды и некоторых аргументов, предоставленных пользователем, включая попытку внедрения команды:

$command = 'Write-Host'
$arguments = @(
  'Legitimate message'
  ';'
  'Write-Host'
  'malware'
)

Давайте посмотрим, что произойдет, когда мы создадим строку и передадим ее Invoke-Expression, как вы это делали до сих пор:

PS ~> $expression = "$command $arguments"
PS ~> Invoke-Expression $expression
Legitimate message
malware

Как видите, Invoke-Expression с радостью оценил как целевую команду, так и команду Write-Host malware, добавленную в конце.

Давайте попробуем то же самое с оператором вызова:

PS ~> & $command @arguments
Legitimate message ; Write-Host malware

Как вы видите здесь, все аргументы были переданы просто так — без вызова каких-либо дополнительных команд, введенных вызывающей стороной.

Этот пример блестяще и ясно иллюстрирует разницу между & и Invoke-Expression. Спасибо, что помогли новичку в PowerShell разобраться в этой тонкости. Ответ принят и за него проголосовали, и теперь я собираюсь рассмотреть некоторые другие функции, в которых я заменил Invoke-Expression на &, чтобы убедиться, что я сделал это правильно.

sbridewell 27.07.2024 17:18

Другие вопросы по теме