在 C 中,使用 POSIX 调用,如何确定路径是否位于目标目录内?
例如,Web 服务器的根目录位于/srv
, 这是getcwd()
对于守护进程。
解析请求时/index.html
,它返回的内容/srv/index.html
.
如何过滤掉对外部路径的请求/srv
?
/../etc/passwd
,
/valid/../../etc/passwd
,
etc.
分割路径于/
并拒绝任何包含的数组..
将破坏有效访问/srv/valid/../index.html
.
有没有一种规范的方法可以通过系统调用来做到这一点?或者我是否需要手动遍历路径并计算目录深度?
总有realpath http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html:
The 真实路径()函数应从 *file_name* 指向的路径名派生一个解析为同一目录条目的绝对路径名,其解析不涉及“.”。 、 '..' 或符号链接。
然后比较什么realpath
为您提供所需的根目录并查看它们是否匹配。
您还可以在添加之前通过展开双点来手动清理文件名"/srv"
。用斜线分割传入路径并逐段遍历它。如果你得到一个"."
然后将其移除并继续;如果你得到一个".."
,然后删除它和前一个组件(注意不要超过列表中的第一个条目);如果您得到其他任何内容,请继续进行下一个组件。然后将剩下的内容粘贴在一起,并在组件之间添加斜线,并在前面添加您的内容"/srv/"
。所以如果有人给你"/valid/../../etc/passwd"
,你最终会得到"/srv/etc/passwd"
and "/where/is/../pancakes/house"
最终将成为"/srv/where/pancakes/house"
.
这样你就无法出去"/srv"
(当然除了通过符号链接)和传入"/../.."
将与以下相同"/"
(就像在普通文件系统中一样)。但你仍然想使用realpath
如果你担心象征性的问题"/srv"
.
逐个组件地使用路径名还可以让您断开向外界呈现的布局与实际文件系统布局之间的连接;没有必要"/this/that/other/thing"
映射到实际的"/srv/this/that/other/thing"
文件的任何位置,路径可能只是某种数据库中的键或某种函数调用的命名空间路径。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)