Меня снова вызвали комментарий на недавний вопрос PowerShell от @Ansgar Wiechers: DO NOT use Invoke-Expression
в отношении секретного вопроса, который у меня давно есть где-то в глубине души спросить.
Сильное утверждение (со ссылкой на статью Invoke-Expression, считающуюся вредной ) предполагает, что вызов сценария, который может перезаписывать переменные, считается вредным.
Также PSScriptAnalyzer рекомендует не использовать Invoke-Expression
, см. Правило AvoidUsingInvokeExpression .
Но однажды я сам использовал технику для обновления общей переменной в рекурсивном скрипте, который может фактически перезаписать значение в любой из родительских областей, что так просто:
([Ref]$ParentVariable).Value = $NewValue
Насколько я могу определить, что потенциальный злонамеренный скрипт мог бы использовать эту технику для внедрения переменных в любом случае, независимо от того, как он вызывается ...
Рассмотрим следующий «вредоносный» скрипт Inject.ps1
:
([Ref]$MyValue).Value = 456
([Ref]$MyString).Value = 'Injected string'
([Ref]$MyObject).Value = [PSCustomObject]@{Name = 'Injected'; Value = 'Object'}
Мой Test.ps1
скрипт:
$MyValue = 123
$MyString = "MyString"
$MyObject = [PSCustomObject]@{Name = 'My'; Value = 'Object'}
.\Inject.ps1
Write-Host $MyValue
Write-Host $MyString
Write-Host $MyObject
Результат:
456
Injected string
@{Name=Injected; Value=Object}
Как видите, все три переменные в области действия Test.ps1
перезаписываются сценарием Inject.ps1
. Это также можно сделать с помощью командлета Invoke-Command, и даже не имеет значения, задаю ли я область видимости переменной Private
:
New-Variable -Name MyValue -Value 123 -Scope Private
$MyString = "MyString"
$MyObject = [PSCustomObject]@{Name = 'My'; Value = 'Object'}
Invoke-Command {
([Ref]$MyValue).Value = 456
([Ref]$MyString).Value = 'Injected string'
([Ref]$MyObject).Value = [PSCustomObject]@{Name = 'Injected'; Value = 'Object'}
}
Write-Host $MyValue
Write-Host $MyString
Write-Host $MyObject
Есть ли способ полностью изолировать вызываемый скрипт / команду от перезаписи переменных в текущей области?
Если нет, то может ли это рассматриваться как угроза безопасности для запуска сценариев каким-либо образом?