检查文件是否驻留在基本目录中的最安全方法是什么?

Go 在任何平台上验证给定文件路径是否位于基本路径内的最安全方法是什么?

这些路径最初以字符串形式提供,并使用“/”作为分隔符,但它们是用户提供的,我需要假设大量恶意输入。我应该执行哪种类型的路径规范化来确保评估诸如“..”之类的序列,以便我可以安全地检查基本路径?各种文件系统和平台上有哪些需要注意的例外情况?哪些 Go 库在这方面应该是安全的?

结果将被提供给外部函数,例如os.Createsqlite3.Open,并且任何未能识别出基本路径已离开的行为都将构成安全违规。


杨__羊羊
浏览 101回答 1
1回答

慕容708150

我相信你可以使用filepath.Rel这个(并检查它是否返回一个不以 开头的值..)。当使用中间分隔符连接到基本路径时,Rel 返回一个在词法上等同于 targpath 的相对路径。也就是说,Join(basepath, Rel(basepath, targpath)) 相当于 targpath 本身。成功时,返回的路径将始终相对于基本路径,即使基本路径和目标路径不共享任何元素。如果无法使 targpath 相对于基本路径或者需要知道当前工作目录来计算它,则会返回错误。Rel 对结果调用 Clean。filepath.Rel还调用filepath.Clean其输入路径,解析任何.s 和..s。Clean 通过纯词法处理返回与 path 等效的最短路径名。它迭代地应用以下规则,直到无法进行进一步的处理:将多个分隔符元素替换为单个分隔符元素。消除每一个 . 路径名元素(当前目录)。消除每个内部 .. 路径名元素(父目录)及其前面的非 .. 元素。消除开始根路径的 .. 元素:即,在路径开头用“/”替换“/..”,假设分隔符为“/”。您也可以filepath.Clean直接使用并在完成后检查前缀。以下是 的一些示例输出filepath.Clean:ps := []string{    "/a/../b",    "/a/b/./c/../../d",    "/b",}for _, p := range ps {    fmt.Println(p, filepath.Clean(p))}印刷:/a/../b /b/a/b/./c/../../d /a/d/b /b也就是说,路径操作不应该是您部署的唯一安全机制。如果您确实担心被利用,请通过沙箱、创建虚拟文件系统/容器等进行深度防御。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go