Go 1.24 - os.Root 锁定工作目录

建议点击 查看原文 查看最新内容。

原文链接: https://typonotes.com/posts/2025/05/16/os-root-in-go124/

os.Root 可以锁定工作目录。 使用户无法打开目录外的文件,例如 ../../../etc/passwd 。 可以算一种 安全保护

最重要的是 强制约束用户, 限制用户行为, 检查计划外的使用逻辑 。 免得和煞笔瞎掰扯, 浪费时间。

  1. 使用 root, _ := os.OpenRoot(basedir) 锁定工作目录
  2. 以后的所有操作都要基于 root.Xzzzz() 展开
  3. root.OpenFile(path) 在打开文件之前, 会判断 文件路径 的合法性。 basedir 之外的路径拒绝访问。
    1. path 可以是绝对路径。
    2. path 也可以是基于 basedir 的相对路径。

invalid-file-path.png

  1. 美中不足: 不支持 root.ReadFile(path) 这样的快捷 API。 还是需要分成 root.OpenFileio.ReadAll。 有点不习惯了。

Code Demo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
	"bytes"
	"io"
	"os"
)

// demo
var configdir = "/tmp/go-demo-os-root/configdir"

func main() {

	_ = os.MkdirAll(configdir, 0755)

	// os.OpenRoot 打开并锁定目录
	root, err := os.OpenRoot(configdir)
	if err != nil {
		panic(err)
	}

	// root.OpenFile 打开文件, 可以是基于 root 的相对路径
	f, err := root.OpenFile("../main.go", os.O_RDONLY, 0644)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	// 不支持 os.ReadFile 这样的快捷方式。
	// 使用 io 读取文件
	_, err = io.ReadAll(f)
	if err != nil {
		panic(err)
	}

	// ... omit
}