Home > Mobile >  Check if a file is in the current directory or its children using C
Check if a file is in the current directory or its children using C

Time:01-16

I am writing a small HTTP web server in C as part of a hobby project, and I need to serve static files. However, one problem I want to avoid is a user typing in, for example, http://example.com/../passwd. To ensure that users don't enter in a malicious path, I want to check if a path entered is in the current parent directory.

My current approach is to use std::filesystem::directory_iterator, checking if the provided one is a file and if its the same as the one provided. However, this is very slow and clunky, and I believe that there is a better solution.

CodePudding user response:

A better solution would be to simply append the user's specified path to your desired root path, canonicalize the result, and then check if the result is still within the root path.

For example, when the user requests http://example.com/../passwd, your server will see a request like:

GET /../passwd HTTP/1.1

So, append just "../passwd" to your root folder and compare the result, for example:

#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...
}
  • Related