如何确定路径是否在目录中?(POSIX)

Job*_*fey 6 c posix

在C中,使用POSIX调用,如何确定路径是否在目标目录中?

例如,Web服务器的根目录在/srv,这是getcwd()守护进程.在解析请求时/index.html,它返回的内容/srv/index.html.

如何过滤掉外部路径的请求/srv

/../etc/passwd, /valid/../../etc/passwd等等.

拆分路径/并拒绝任何包含的数组..将破坏有效访问/srv/valid/../index.html.

有系统调用的规范方法吗?或者我是否需要手动遍历路径并计算目录深度?

mu *_*ort 6

总是realpath:

真实路径()函数要计算,从路径指向*FILE_NAME*,绝对路径解析到同一个目录项,其分辨率不涉及"" ,'..'或符号链接.

然后比较一下realpath为您提供所需的根目录,看看它们是否匹配.

您也可以通过在前置之前展开双点来手动清理文件名"/srv".将传入路径拆分为斜线并逐个遍历.如果你得到一个"."然后将其移除并继续前进; 如果你得到一个"..",那么删除它和前一个组件(注意不要超过列表中的第一个条目); 如果您还有其他任何内容,请转到下一个组件.然后将左边的内容与组件之间的斜杠粘贴在一起并添加前面的"/srv/".所以,如果有人给你"/valid/../../etc/passwd",你会拥有"/srv/etc/passwd""/where/is/../pancakes/house"将结束作为"/srv/where/pancakes/house".

这样你就无法到外面"/srv"(当然除了通过符号链接)和传入"/../.."将是相同的"/"(就像在普通文件系统中一样).但是realpath如果你担心象征性的话,你仍然想要使用"/srv".

逐个组件使用路径名称还可以打破您呈现给外部世界的布局与实际文件系统布局之间的连接; 没有必要在任何地方"/this/that/other/thing"映射到实际"/srv/this/that/other/thing"文件,路径可能只是某种数据库中的键或函数调用的某种命名空间路径.