• Go1.24 中的新特性分享
  • 发布于 2个月前
  • 460 热度
    0 评论
马上就要到 2025 年啦。Go1.24 又即将如期而至。接下来将给大家逐步带来新版本的特性更新。今天要给大家介绍的是 Go 在标准库 os 上做的一个安全方面的增强。有兴趣的同学可以后续在功能上保持跟进。

提案背景
在安全方面,目录遍历漏洞是一类常见的漏洞,攻击者会诱使程序打开一个它在原本的程序逻辑中并没有计划打开的文件。这些攻击通常采取提供相对路径名的形式,例如:./../.../etc/passwd,从而导致访问预定位置之外的文件。像是近期发生的 CVE-2024-3400[1](GlobalProtect 中的任意文件创建导致操作系统命令注入漏洞)是最近一个真实的目录遍历导致远程代码执行漏洞被主动利用的例子。

与此相关但较少被利用的一类漏洞,还有像是:软链接(也称:符号链接,symbolic link)遍历,即攻击者在文件系统中创建一个软链接,并操纵目标链接软链接。因此提案原作者@Damien Neil,建议在 os 软件包中添加几个新函数,以帮助安全地打开带有不受信任的文件名组件的文件,并防御软链接遍历。

标准库 os 干什么的
标准库 os 主要是提供文件系统的相关功能,对外提供的接口独立于平台的接口,设计类似于 Unix。
最简单的例子:
file, err := os.Open("file.go") // For read access.
if err != nil {
 log.Fatal(err) // 堆代码 duidaima.com
}
好了,四舍五入你已经理解了。

Go1.24 新特性:支持限定目录使用
在 Go1.24 中,新增了 os.Root 的类型,其提供了在特定目录中执行文件系统操作的能力。整个体系是围绕着这个新类型进行的。对应的核心函数是 os.OpenRoot,函数打开一个目录并返回一个 os.Root。os.Root 上的方法仅允许在目录内操作,不允许指向目录外部位置的路径,包括遵循目录外符号链接的路径。(防御住了前面提案背景提到的攻击范围)

具体 Go1.24 支持的方法如下:
type Root struct { ... }
func OpenRoot(dir string) (*Root, error)
func (*Root) OpenFile(name string, flag int, perm FileMode) (*File, error)
func (*Root) Create(name string) (*File, error)
func (*Root) Open(name string) (*File, error)
func (*Root) OpenRoot(name string) (*Root, error)
func (*Root) Close() error
func (*Root) Mkdir(name string, perm FileMode) error
func (*Root) Remove(name string) error
func (*Root) Lstat(name string) (FileInfo, error)
func (*Root) Stat(name string) (FileInfo, error)
简单的使用例子:
func OpenInRoot(dir, name string) (*File, error) {
   r, err := OpenRoot(dir)
   if err != nil { return nil }
   return r.Open(name)
}
预计 Go1.25 才会实现:
func (*Root) MkdirAll
func (*Root) RemoveAll
func (*Root) Chmod
func (*Root) Chown
func (*Root) Chtimes
func (*Root) Lchown
func (*Root) Readlink
func (*Root) Rename
func (*Root) Symlink
func (*Root) Link
func (*Root) Truncate
总结
今天我们给大家分享了 Go1.24 中的新特性之一,主要是对于标准库 os 中文件系统的部分增强了特定目录中执行文件系统操作能力,用于防止目录遍历的漏洞。这其实有些相像,因为之前 Google 也有专门针对此的 Go 开源库。也可以认为是一次简单增强的知识回流了。
用户评论