@Ansgar Wiechers 对最近 PowerShell 问题的评论再次触发了我:DO NOT use Invoke-Expression关于一个安全问题,我已经在脑海中思考了很长时间并且需要问。
强烈的声明(参考调用表达式被认为是有害的文章)表明,调用可以覆盖变量的脚本被认为是有害的。
还有PS脚本分析器建议不要使用Invoke-Expression
,参见避免使用InvokeExpression规则.
但我自己曾经使用过一种技术来更新递归脚本中的公共变量,该变量实际上可以覆盖其任何父作用域中的值,就像这样简单:
([Ref]$ParentVariable).Value = $NewValue
据我所知,潜在的恶意脚本可以使用此技术在任何情况下注入变量,无论它是如何调用的......
考虑以下“恶意”Inject.ps1
script:
([Ref]$MyValue).Value = 456
([Ref]$MyString).Value = 'Injected string'
([Ref]$MyObject).Value = [PSCustomObject]@{Name = 'Injected'; Value = 'Object'}
My Test.ps1
script:
$MyValue = 123
$MyString = "MyString"
$MyObject = [PSCustomObject]@{Name = 'My'; Value = 'Object'}
.\Inject.ps1
Write-Host $MyValue
Write-Host $MyString
Write-Host $MyObject
Result:
456
Injected string
@{Name=Injected; Value=Object}
正如您所看到的所有三个变量Test.ps1
范围被覆盖Inject.ps1
脚本。这也可以使用 Invoke-Command cmdlet 来完成,并且我是否将变量的范围设置为Private
either:
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
有没有办法完全隔离调用的脚本/命令以覆盖当前范围内的变量?
如果不是,这是否可以被视为以任何方式调用脚本的安全风险?