使用C++检查文件是否在当前目录或其子目录中

ix0qys7i  于 2023-01-18  发布在  其他
关注(0)|答案(1)|浏览(146)

我正在用C++编写一个小型HTTP Web服务器,这是我爱好项目的一部分,我需要提供静态文件。但是,我想避免的一个问题是用户键入,例如http://example.com/../passwd。为了确保用户不会输入恶意路径,我想检查输入的路径是否在当前父目录中。
我目前的方法是使用std::filesystem::directory_iterator,检查提供的文件是否是一个文件,以及它是否与提供的文件相同。但是,这非常缓慢和笨重,我相信有一个更好的解决方案。

hjqgdpho

hjqgdpho1#

一个更好的解决方案是将用户指定的路径附加到所需的根路径,规范化结果,然后检查结果是否仍在根路径中。
例如,当用户请求http://example.com/../passwd时,您的服务器将看到如下请求:

GET /../passwd HTTP/1.1

因此,只需将"../passwd"附加到根文件夹并比较结果,例如:

#include <string>
#include <filesystem>
namespace fs = std::filesystem;

bool isSubDir(fs::path p, fs::path root)
{
    static const fs::path emptyPath;
    while (p != emptyPath) {
        if (fs::equivalent(p, root)) {
             return true;
        }
        p = p.parent_path();
    }
    return false;
}

...

fs::path requestedPath = fs::path("../passwd").make_preferred();
fs::path parentPath = fs::path("C:\\webroot\\");
fs::path actualPath = fs::canonical(parentPath / requestedPath);

if (isSubDir(actualPath, parentPath))
{
    // serve file at actualPath as needed...
}
else
{
    // send error reply...
}

相关问题