【发布时间】:2010-11-02 07:57:09
【问题描述】:
我正在编写一个类似于 FTP 的小型只读服务器。客户说“给我那个文件”,然后我的服务器发送它。
是否有任何标准方法(库函数?!?)来确保请求的文件不是“../../../../../etc/passwd”或任何其他坏事?如果我可以将所有查询限制在一个目录(及其子目录)中,那就太好了。
谢谢!
【问题讨论】:
标签: c++ linux unix path sanitization
我正在编写一个类似于 FTP 的小型只读服务器。客户说“给我那个文件”,然后我的服务器发送它。
是否有任何标准方法(库函数?!?)来确保请求的文件不是“../../../../../etc/passwd”或任何其他坏事?如果我可以将所有查询限制在一个目录(及其子目录)中,那就太好了。
谢谢!
【问题讨论】:
标签: c++ linux unix path sanitization
获取根 (/) 目录和服务目录(例如 /ftp/pub)的 inode。对于他们请求的文件,请确保:
您可以使用stat 查找任何目录的inode。将它放在一个函数中,并在提供文件之前调用它。
当然,使用具有适当权限的用户/组也可以。
【讨论】:
我不知道有什么标准库可以做到这一点。
你可以试试:
将运行服务器的unix用户的权限设置为只对某个目录有读/写权限。 (可能使用 PAM、chroot 环境或使用标准 unix 用户/组权限)
您可以设计您的程序,使其只接受绝对路径(在 unix 中,路径以“/”开头)。这样,您可以检查以确保它是有效路径 - 例如,禁止任何具有字符串“..”的路径
编辑:
来自Peter:看起来有一个库函数realpath() 可以帮助上面的#2。
【讨论】:
Chroot 可能是最好的方法,但您可以使用realpath(3) 来确定给定文件名的规范路径。从手册页:
char *realpath(const char *file_name, char *resolved_name);
realpath() 函数解析所有符号链接、额外的“/”字符以及文件名中对 /./ 和 /../ 的引用,并将生成的绝对路径名复制到解析后的名称所引用的内存中。 resolve_name 参数必须引用能够存储至少 PATH_MAX 个字符的缓冲区。
您可以从那里以您喜欢的任何其他方式限制请求。
【讨论】:
在 Windows 中,我会做类似的事情(尽管仍然适用于任何操作系统):
【讨论】:
.. 遍历。在 Windows 上,使用 GetFullPathName。
也可以看看chroot
【讨论】:
虽然这并不完美,但您可以在特定用户/组下运行您的 ftp 服务器,并且只允许该用户/组访问某些目录。但是,这可能不是您想要的。
您还可以有一个用户可以访问的目录白名单,以及他们尝试访问的任何其他目录,您根本不允许(因此,基本上是建立您自己的权限)。
我个人更喜欢前者,因为操作系统已经为你完成了这项工作。
【讨论】: