> ## Content Index
> Fetch the complete content index at: https://huizhou92.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# go1.24: 新的标准库 os.Root
- URL: https://huizhou92.com/go1-24-xin-de-biao-zhun-ku-os-root/
- Published: 2024-12-10T11:23:31.000Z
- Updated: 2026-09-06T11:39:41.000Z
- Description: go1.24: 新的标准库 os.Root. Backlink | |Photo by Kaleidico on Unsplash Golang 1.24 已经进入冻结期了，目前很多特性我们在 Go 1.24 Release Notes 能够看到，接下来一段时间我会学习Golang1.24将会添加的新功能以及。
- Author: huizhou92
- Tags: tech, golang, go1_24, #lang-zh-cn

![man drawing on dry-erase board](https://images.unsplash.com/photo-1532619187608-e5375cab36aa?ixid=M3wzNjAwOTd8MHwxfHNlYXJjaHwxNnx8ZGV2ZWxvcHxlbnwwfDB8fHwxNzM1NjI2NzU1fDA&ixlib=rb-4.0.3)

[Backlink](https://unsplash.com/photos/man-drawing-on-dry-erase-board-7lryofJ0H9s?ref=huizhou92.com) | |Photo by [Kaleidico](https://unsplash.com/@kaleidico?utm%5Fsource=Obsidian%20Image%20Inserter%20Plugin&utm%5Fmedium=referral) on [Unsplash](https://unsplash.com/?utm%5Fsource=Obsidian%20Image%20Inserter%20Plugin&utm%5Fmedium=referral) 

Golang 1.24 已经进入冻结期了，目前很多特性我们在[Go 1.24 Release Notes](https://tip.golang.org/doc/go1.24?ref=huizhou92.com) 能够看到，接下来一段时间我会学习Golang1.24将会添加的新功能以及修改点。如果您也想学习Go最新的进展，请关注我，  
这篇文章，我们将学习一下[os.Root](https://tip.golang.org/pkg/os?ref=huizhou92.com#Root)这个新增的Standard library。

### Proposal

> 目录遍历漏洞是一类常见的漏洞，攻击者会诱骗程序打开其不希望的文件。这些攻击通常采用提供相对路径名的形式，例如`"../../../etc/passwd"` ，这会导致在预期位置之外进行访问。 [CVE-2024-3400](https://nvd.nist.gov/vuln/detail/CVE-2024-3400?ref=huizhou92.com)是最近的一个真实的目录遍历示例，导致远程代码执行漏洞被主动利用。

在其他语言以及操作系统中，已经都有类似的实现, 比如:

- Python 的 chroot：通过 os.chroot() 将根目录限制为特定目录。
- Linux 的文件系统命名空间：通过 mount 和 chroot 限制进程的视图。  
我们可以写一个demo 测试一下。  
首先构造一个 “机密”文件

```shell
echo 'password123' >> /tmp/password

```

然后写一个Golang函数， 原义是打开当前目录的文件

```go
func main() {  
    fileName := os.Args[1]  
    //readFile  
    localFilePath := "."  
    filePath := fmt.Sprintf("%s/%s", localFilePath, fileName)  
    content, err := os.ReadFile(filePath)  
    if err != nil {  
       fmt.Printf("Error reading file %s: %s\n", fileName, err)  
       return  
    }  
    fmt.Printf("File %s opened successfully. file content %s\n", fileName, content)  
}

```

但是因为传入了不可靠的参数，代码能够访问到 权限范围之外的地方。

```shell

➜  os_root git:(main) ✗ pwd
/Users/hxzhouh/workspace/github/me/blog-example/go/go1.24/os_root
➜  os_root git:(main) ✗ ./main ../../../../../../../../../tmp/password
./../../../../../../../../../tmp/password
File ../../../../../../../../../tmp/password opened successfully. file content password123

```

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

```go
func main() {  
    fileName := os.Args[1]  
    root, err := os.OpenRoot(".")  
    if err != nil {  
       panic(err)  
    }  
    file, err := root.Open(fileName)  
    if err != nil {  
       fmt.Println(fmt.Sprintf("Error opening file %s: %s\n", fileName, err.Error()))  
       return  
    }  
    content := make([]byte, 1024)  
    c, err := file.Read(content)  
    if err != nil {  
       panic(err)  
    }  
    content = content[:c]  
    fmt.Printf("File %s opened successfully. file content %s\n", fileName, content)  
}

```

再次运行

```shell
➜  os_root git:(main) ✗ gotip version 
go version devel go1.24-fafd447 Wed Dec 11 15:57:34 2024 -0800 darwin/arm64
➜  os_root git:(main) ✗ gotip build -o go1.24  main.go                      
➜  os_root git:(main) ✗ ./go1.24 ../../../../../../../../../tmp/password 
Error opening file ../../../../../../../../../tmp/password: openat ../../../../../../../../../tmp/password: path escapes from parent

```

如果文件夹脱离了`parent` 层级，就会报错。  
更多的APi接口请参考[官方文档](https://pkg.go.dev/os@master?ref=huizhou92.com#Root) 。1.24正式发布后，估计很多第三方库都会第一时间适配把，毕竟其他语言基本上都有这种功能了。