powershell 这些Invoke-Expression的替代品真的更安全吗?为什么?

beq87vna  于 2022-12-23  发布在  Shell
关注(0)|答案(1)|浏览(132)

我不明白Invoke-Expression是否有内部缺陷,使它更危险,或者问题是它将文本合并到代码,代码合并到执行,可能还在本地范围内执行,所有这些都在一个命令中。
我想要做的是通过Add-Type创建一个带有public event EventHandler MyEvent;事件的C#类,然后在PowerShell中继承该类,方法是将PowerShell编写为字符串@'class psMessages: csMessages{<code for clas>}'@,将字符串转换为脚本块,然后执行它。
我发现这些创建脚本块的方法可以工作:

$ScriptBlock = ([System.Management.Automation.Language.Parser]::ParseInput($psMessages, [ref]$null, [ref]$null)).GetScriptBlock()
# or
$ScriptBlock = [scriptblock]::Create($psMessages)

并且这些命令中的任何一个都将在当前作用域中执行脚本块:

. $ScriptBlock
# or
Invoke-Command -NoNewScope $ScriptBlock

**附加信息:**这些命令失败,我相信是因为它们在新的作用域中执行脚本块-如果我说错了,请纠正我:

& $ScriptBlock
# or
$ScriptBlock.Invoke()
# or
Invoke-Command $ScriptBlock

那么,这些方法中有没有比Invoke-Expression更安全的?或者它们都一样危险?如果有更安全的,为什么?

31moq8wy

31moq8wy1#

      • 任何命令的危险之处在于盲目执行来自 * 未知/不可信 * 源**的源代码。
  • 因此,执行 * 机制 * 是问题的附带因素。
  • 相反,这意味着如果您 * 完全控制 * 或 * 隐式信任 * 给定的源代码片段,则使用Invoke-Expression-即generally to be avoided-* 是 * 可接受的
  • 注意,由Invoke-Expression执行的代码总是在 * current * 作用域中运行;可以将输入字符串 Package 在& { ... }中,以便在 * child * 作用域中执行它。
  • 正如Santiago Squarzon所指出的,[scriptblock]::Create()实现了一个 * 中间地带*:
  • 正如他在this answer中所演示的,**可以根据允许的命令、对特定变量的读访问以及是否允许对环境变量的读访问来 * 约束 * 可以执行的内容。
  • 此外,[scriptblock]::Create()返回的script block示例允许按需进行潜在的可重用调用,可以选择在 * current * 作用域中使用.(点源操作符)执行它,或者在 * child * 作用域中使用&(调用操作符)执行它。

至于"附加信息:"下面列出的命令

  • 他们不应该失败;它们都应该在一个 * child * 作用域中执行脚本块。
  • 然而:
  • 应该避免在脚本块上使用.Invoke()方法,因为它在几个方面改变了调用的语义-参见this answer
  • 类似地,使用Invoke-Command来(本地)调用脚本块也没有什么好理由-参见this answer

相关问题