【问题标题】:Path sanitization in C++C++ 中的路径清理
【发布时间】:2010-11-02 07:57:09
【问题描述】:

我正在编写一个类似于 FTP 的小型只读服务器。客户说“给我那个文件”,然后我的服务器发送它。

是否有任何标准方法(库函数?!?)来确保请求的文件不是“../../../../../etc/passwd”或任何其他坏事?如果我可以将所有查询限制在一个目录(及其子目录)中,那就太好了。

谢谢!

【问题讨论】:

    标签: c++ linux unix path sanitization


    【解决方案1】:

    获取根 (/) 目录和服务目录(例如 /ftp/pub)的 inode。对于他们请求的文件,请确保:

    1. 文件存在。
    2. 文件的父文件(在文件路径上使用多个“/..”访问)在访问根目录 inode 之前先访问了服务目录 inode。

    您可以使用stat 查找任何目录的inode。将它放在一个函数中,并在提供文件之前调用它。

    当然,使用具有适当权限的用户/组也可以。

    【讨论】:

    • 很高兴你接受了我的建议,尽管我认为 chroot 也是完成你想要的事情的好方法。
    • 索引节点仅在一个文件系统中是唯一的。您的解决方案没有考虑到这一点。
    【解决方案2】:

    我不知道有什么标准库可以做到这一点。

    你可以试试:

    1. 将运行服务器的unix用户的权限设置为只对某个目录有读/写权限。 (可能使用 PAM、chroot 环境或使用标准 unix 用户/组权限)

    2. 您可以设计您的程序,使其只接受绝对路径(在 unix 中,路径以“/”开头)。这样,您可以检查以确保它是有效路径 - 例如,禁止任何具有字符串“..”的路径

    编辑:

    来自Peter:看起来有一个库函数realpath() 可以帮助上面的#2。

    【讨论】:

      【解决方案3】:

      Chroot 可能是最好的方法,但您可以使用realpath(3) 来确定给定文件名的规范路径。从手册页:

       char *realpath(const char *file_name, char *resolved_name);
      

      realpath() 函数解析所有符号链接、额外的“/”字符以及文件名中对 /./ 和 /../ 的引用,并将生成的绝对路径名复制到解析后的名称所引用的内存中。 resolve_name 参数必须引用能够存储至少 PATH_MAX 个字符的缓冲区。

      您可以从那里以您喜欢的任何其他方式限制请求。

      【讨论】:

        【解决方案4】:

        在 Windows 中,我会做类似的事情(尽管仍然适用于任何操作系统):

        1. 用户请求文件
        2. 服务器找到文件
        3. 服务器检查 path_to_file 是否以“C:/SomeFolderWithFiles/”开头
        4. 完成交易

        【讨论】:

        • 没有。这不会阻止 .. 遍历。在 Windows 上,使用 GetFullPathName
        【解决方案5】:

        也可以看看chroot

        【讨论】:

          【解决方案6】:

          虽然这并不完美,但您可以在特定用户/组下运行您的 ftp 服务器,并且只允许该用户/组访问某些目录。但是,这可能不是您想要的。

          您还可以有一个用户可以访问的目录白名单,以及他们尝试访问的任何其他目录,您根本不允许(因此,基本上是建立您自己的权限)。

          我个人更喜欢前者,因为操作系统已经为你完成了这项工作。

          【讨论】:

            猜你喜欢
            • 2016-08-20
            • 2012-04-29
            • 2012-03-12
            • 1970-01-01
            • 2013-02-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多