os.lstat 是判断符号链接的唯一可靠方式,因 os.stat 会跳转到目标而失效;需用 os.lstat 检查 modesymlink 标志,并配合 filepath.evalsymlinks 和前缀校验实现安全路径准入。

os.Lstat 是判断符号链接的唯一可靠方式
想确认一个路径是不是软链接,os.Stat 会直接跳转到目标并返回目标文件信息,完全不可靠;必须用 os.Lstat——它只读取路径自身的 inode 元数据,不解析链接内容。
常见错误现象:os.Stat("mylink") 返回 /etc/passwd 的信息,你以为在操作普通文件,其实已落入符号链接陷阱。
-
fi, err := os.Lstat(path)后检查fi.Mode() & os.ModeSymlink != 0才是唯一可信判断 - 在 rootless 容器或只读挂载点上,
os.Lstat可能因权限失败,需配合os.IsPermission(err)做降级处理 - Windows 上若链接指向不存在的目标,
os.Lstat可能返回file does not exist,而非明确的链接类型信息
filepath.EvalSymlinks 解析路径但不校验安全性
filepath.EvalSymlinks 会递归解析所有符号链接,最终返回一个“物理路径”,但它不做任何访问控制或白名单检查——如果你传入 /var/www/uploads/link_to_etc_passwd,它就真给你返回 /etc/passwd。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
使用场景中容易忽略这点:它只是路径规范化工具,不是安全网关。
- 永远不要单独依赖
filepath.EvalSymlinks做权限判断;它应和白名单前缀比对配合使用 - 解析结果可能超出预期目录层级(如
../../../etc/shadow),需用strings.HasPrefix(realPath, allowedBase)显式校验 - 遇到循环链接时,
filepath.EvalSymlinks默认最多解析 255 层,超限返回too many levels of symbolic links错误
安全路径准入必须三步原子判断
真正安全的路径准入流程,需要三步原子判断:先确认是否为链接、再解析真实路径、最后比对是否落在可信范围内。缺一不可。
- 第一步:
os.Lstat检出os.ModeSymlink→ 若是,可拒绝、记录或进入深度校验 - 第二步:
filepath.EvalSymlinks获取绝对物理路径 → 注意捕获os.IsNotExist(坏链)和os.IsPermission(无权访问目标) - 第三步:用
filepath.Clean和strings.HasPrefix确保cleanedRealPath以允许前缀开头,且不含..跳转成分
硬编码路径拼接或跳过 Lstat 直接 EvalSymlinks,等于把门钥匙交给攻击者。最易被忽略的是:坏链(dangling symlink)既不是有效文件,也不是安全链接,但它依然存在——os.Lstat 能看见它,os.Stat 和 filepath.EvalSymlinks 都会失败,这个中间态必须显式处理。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










