问题描述
我在@Ansgar Wiechers对最近的PowerShell问题的评论中再次被触发:来解决我很久以来一直想问的一个安全问题。
I was triggered again on a comment on a recent PowerShell question from @Ansgar Wiechers: DO NOT use Invoke-Expression
with regards to a security question I have for a long time somewhere in the back of my mind and need to ask.
强有力的声明(引用文章)表明,调用可以覆盖变量的脚本是有害的。
The strong statement (with a reference to the Invoke-Expression considered harmful article) suggests that an invocation of a script that can overwrite variables is considered harmful.
建议不要使用 Invoke-Expression
,请参见安装Module -Scope CurrentUser ThreadJob );例如:
As a thread job, via the
Start-ThreadJob
cmdlet (ships with PowerShell [Core] 6+; in Windows PowerShell, it can be installed from the PowerShell Gallery with something likeInstall-Module -Scope CurrentUser ThreadJob
); e.g.:
-
Start-ThreadJob {./someUntrustedScript.ps1} |接收作业-等待-自动删除
Start-ThreadJob { ./someUntrustedScript.ps1 } | Receive-Job -Wait -AutoRemove
通过创建新运行空间通过PowerShell SDK;例如:
By creating a new runspace via the PowerShell SDK; e.g.:
-
[powershell] :: Create()。AddScript({./someUntrustedScript.ps1})。 Invoke()
- 请注意,您必须付出额外的努力才能使输出流 other 而不是成功流。错误流的输出;同样,在命令完成后,应该在PowerShell实例上调用
.Dispose()
。
[powershell]::Create().AddScript({ ./someUntrustedScript.ps1 }).Invoke()
- Note that you'll have to do extra work to get the output streams other than the success one, notably the error stream's output; also,
.Dispose()
should be called on the PowerShell instance on completion of the command.
基于子进程的解决方案将很慢并且在以下方面受到限制您可以返回的数据类型(由于涉及序列化/反序列化),但是它提供了隔离机制,以防止所调用的代码使进程崩溃。
A child process-based solution will be slow and limited in terms of data types you can return (due to serialization / deserialization being involved), but it provides isolation against the invoked code crashing the process.
基于线程的作业速度更快,可以返回任何数据类型,但可能会使整个过程崩溃。
A thread-based job is much faster, can return any data type, but can crash the entire process.
在所有情况下,您都必须以 arguments 的形式传递调用者需要访问的任何值,或者使用后台作业和线程作业,或者通过 $使用:
范围说明符。
In all cases you will have to pass any values from the caller that the invoked code needs access to as arguments or, with background jobs and thread jobs, alternatively via the $using:
scope specifier.
提到了其他不太理想的替代方法:
js2010 mentions other, less desirable alternatives:
-
Start-Process
(基于子进程,具有纯文本参数和输出)
Start-Process
(child process-based, with text-only arguments and output)
,它们已经过时了(不会移植到PowerShell Core ,并且不会)。
PowerShell Workflows, which are obsolescent (they weren't ported to PowerShell Core and won't be).
使用 Invoke-Command
与环回远程处理( -ComputerName localhost
)假设也是一种选择,但是这会导致子进程和基于HTTP的通信的双重开销;另外,您必须为远程计算机设置计算机,并且必须以高程运行(以管理员身份)。
Using Invoke-Command
with "loopback remoting" (-ComputerName localhost
) is hypothetically also an option, but then you incur the double overhead of a child process and HTTP-based communication; also, your computer must be set up for remoting, and you must run with elevation (as administrator).
这篇关于如何防止在PowerShell中进行变量注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!