rglob() 单独使用不安全,因其默认跟随符号链接且不校验路径是否超出根目录,易被恶意软链诱导遍历系统文件;应先 resolve() 再用 is_relative_to() 校验。

直接用 pathlib.Path.rglob() 最安全,但必须配合 resolve() 和路径合法性校验,否则可能被符号链接绕过限制或触发循环遍历。
为什么 rglob() 单独用不安全?
rglob() 本身不检查符号链接、不验证路径是否超出预期根目录。如果目录里有恶意构造的软链(比如指向 /etc 或上级目录),它会一路跟进去——这在处理用户上传的压缩包解压目录或第三方数据时极危险。
- 现象:调用
Path("user_upload").rglob("*")却意外读到了系统配置文件 - 根本原因:
rglob()默认跟随符号链接,且不做路径规范化比对 - 正确做法:先
resolve()得到绝对真实路径,再逐个判断是否仍在授权根内
如何做路径合法性校验?
核心是用 resolve() + is_relative_to(),但要注意 Python 版本兼容性。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- Python 3.9+:直接用
if p.resolve().is_relative_to(root): process(p) - Python str(p.resolve()).startswith(str(root.resolve()) + "/")(注意结尾加斜杠防前缀误判)
- 必须对每个遍历出的
Path单独校验——不能只校验起始路径,因为中间可能有软链跳转 - 遇到
FileNotFoundError或PermissionError要捕获,避免中断整个遍历
要不要用 glob("**/*") 替代 rglob()?
不要。两者行为一致,** 在 glob() 中同样默认跟随符号链接,且写法更易出错(比如漏写 /**/* 导致只查当前层)。
-
rglob("*")语义清晰,明确表达“递归所有子项” -
glob("**/*")依赖 shell 风格通配符解析,某些 pathlib 版本对**的边界处理不一致 - 性能上无差异,但可读性和维护性
rglob()更稳
真正容易被忽略的是:即使做了 resolve() 和 is_relative_to(),也要在打开文件前再次检查——因为从遍历到打开之间,路径可能已被篡改为软链。生产环境建议搭配 follow_symlinks=False(需用 os.open(..., os.O_NOFOLLOW) 底层控制)或直接禁用符号链接挂载。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










