Golang中go version -m使用-trimpath的意外副作用

Golang中go version -m使用-trimpath的意外副作用 大家好,

我们想在构建时使用 -ldflags -X 将一个(不算很)秘密嵌入到可执行文件中。但我们发现,如果直接使用 go version -m yourexe 命令,这些 ldflags 会被打印出来。

当我们在构建时添加 -trimpath 标志后,ldflags 就从 go version 的输出中消失了,这很棒,但这并不是该标志文档中描述的行为。

请问这是预期的行为,还是工具中的一个 bug?或者这个特性是否会在未来的 Go 版本中消失?

感谢您的帮助。

例如:

package main
import "fmt"
var ASecret = ""

func main() {
   fmt.Println(ASecret)
}
jonrichards@UNKNOWN Downloads % go build -ldflags="-X main.ASecret=123"  main.go
jonrichards@UNKNOWN Downloads % ./main 
123
jonrichards@UNKNOWN Downloads % go version -m main                              
main: go1.23.3
	path	command-line-arguments
	build	-buildmode=exe
	build	-compiler=gc
	build	-ldflags="-X main.ASecret=123"
	build	CGO_ENABLED=1
	build	CGO_CFLAGS=
	build	CGO_CPPFLAGS=
	build	CGO_CXXFLAGS=
	build	CGO_LDFLAGS=
	build	GOARCH=arm64
	build	GOOS=darwin
	build	GOARM64=v8.0
jonrichards@UNKNOWN Downloads % go build -trimpath -ldflags="-X main.ASecret=123"  main.go
jonrichards@UNKNOWN Downloads % go version -m main                                        
main: go1.23.3
	path	command-line-arguments
	build	-buildmode=exe
	build	-compiler=gc
	build	-trimpath=true
	build	CGO_ENABLED=1
	build	GOARCH=arm64
	build	GOOS=darwin
	build	GOARM64=v8.0

更多关于Golang中go version -m使用-trimpath的意外副作用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

确实如此。感谢您的及时回复。

更多关于Golang中go version -m使用-trimpath的意外副作用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好,这是一个已知的缺陷,相关跟踪信息可查看此处

这是一个已知的预期行为。-trimpath 标志不仅会移除文件系统路径信息,还会从构建信息中清除所有可能包含敏感数据的构建标志,包括 -ldflags

当使用 -trimpath 时,Go 工具链会过滤掉构建信息中的命令行参数,以防止通过 go version -m 泄露敏感信息。这是设计上的安全特性,而不是文档遗漏或 bug。

示例代码验证:

package main

import (
    "fmt"
    "runtime/debug"
)

var BuildSecret = ""

func main() {
    // 查看构建信息
    if info, ok := debug.ReadBuildInfo(); ok {
        for _, setting := range info.Settings {
            fmt.Printf("%s: %s\n", setting.Key, setting.Value)
        }
    }
    fmt.Println("Secret:", BuildSecret)
}

构建测试:

# 不使用 -trimpath
go build -ldflags="-X main.BuildSecret=my-secret-123" main.go
./main
# 输出会显示 -ldflags 参数

# 使用 -trimpath
go build -trimpath -ldflags="-X main.BuildSecret=my-secret-123" main.go
./main
# 输出不会显示 -ldflags 参数

这个特性在 Go 1.13 引入 -trimpath 时就已经存在,并且会继续保持。如果你需要完全控制构建信息的暴露,可以使用 -buildinfo=false 完全禁用构建信息记录:

go build -buildinfo=false -ldflags="-X main.BuildSecret=my-secret-123" main.go

这样 go version -m 将无法读取任何构建信息。

回到顶部