大家好,猫头虎博主带你深入探索Go的世界!今天的主题是关于最近Go安全更新所解决的关键问题:在不受信任的目录中进行PATH查找,这可能在执行go get
命令时导致远程执行。这篇博客将详细介绍这个漏洞,Go团队是如何修复它的,以及你如何确定自己的程序是否也存在类似的安全隐患。
在软件开发中,安全永远是首要任务。Go的最新安全更新解决了一个关于PATH查找的重要问题,这个问题可能导致在某些条件下执行远程代码。理解这个问题的本质,以及它如何影响Go程序,对于每个Go开发者来说都是至关重要的。
Go命令的一个设计目标是大多数命令(包括go build
、go doc
、go get
、go install
和go list
)不运行从互联网下载的任意代码。但go run
、go test
和go generate
显然是个例外。所以,当go get
被欺骗执行任意代码时,我们认为这是一个安全漏洞。
所有操作系统都有一个可执行路径的概念(Unix上的$PATH
,Windows上的%PATH%
),这是一个目录列表。当你在shell提示符下输入一个命令时,shell会依次在列表中的每个目录中查找具有你输入的名称的可执行文件。它运行找到的第一个文件,或者打印出如“command not found”之类的信息。
当go get
下载并构建包含import "C"
的包时,它运行名为cgo
的程序来准备相关C代码的Go等价物。go
命令在包含包源代码的目录中运行cgo
。一旦cgo
生成了其Go输出文件,go
命令本身调用Go编译器处理生成的Go文件,并调用主机C编译器(如gcc
或clang
)来构建与包一起提供的任何C源文件。但问题在于go
命令如何找到主机C编译器?它在PATH中查找。
为了解决这个问题,Go团队采取了两步策略。首先,go
命令现在会向cgo
传递完整的主机C编译器路径。其次,cgo
、go
和Go发行版中的其他所有命令现在使用os/exec
包的一个变体,该变体会报告错误,如果以前会使用来自当前目录(dot)的可执行文件。
如果你在自己的程序中使用exec.LookPath
或exec.Command
,只有在运行程序的目录包含不受信任内容时才需要担心。在这种情况下,子进程可能会使用来自当前目录而不是系统目录的可执行文件启动。
golang.org/x/sys/execabs
保护你的程序如果你担心自己的程序可能受到类似的影响,可以使用[golang.org/x/sys/execabs
](https://
pkg.go.dev/golang.org/x/sys/execabs)包来增加安全性。你只需要在程序中将
import "os/exec"
替换为
import exec "golang.org/x/sys/execabs"
并重新编译程序。
要点 | 说明 |
---|---|
Go命令与安全问题 | go get被欺骗执行任意代码被视为安全漏洞 |
PATH查找问题 | 漏洞涉及Go和其他程序如何找到可执行文件 |
解决方案 | go命令现在向cgo传递完整的C编译器路径,并修改os/exec包 |
检查自己的程序 | 使用golang.org/x/sys/execabs来增强安全性 |
默认保护os/exec | 讨论更改Windows上exec.Command和exec.LookPath的默认行为 |
这篇文章已被猫头虎的Go生态洞察专栏收录,详情点击这里。