Is the following sufficient to check that a path is not malicious, and is the validation against these rules correct:
- Path must have non-zero length
- It must not be an absolute path
- It should not begin with
-
- The path must not contain any "path operators", that is
..
and .
.
- It should not contain any invisible characters below
. Also, characters that are rejected by Windows API should be disallowed.
Safe/Not malicous here means that the path should not escape current working directory, or screw up the user's directory, regardless of platform.
bool validate_filename(std::span<char const> name)
{
if(std::size(name) == 0)
{ return false; }
if(name[0] == '/' || name[0] == '\' || name[0] == '-')
{ return false; }
auto ptr = std::begin(name);
auto ptr_saved = ptr;
while(ptr != std::end(name))
{
auto ch_in = *ptr;
auto check = [ptr, ptr_saved]() {
auto sv = std::string_view{ptr_saved, ptr};
return sv == "." || sv == ".." || sv == "";
};
++ptr;
switch(ch_in)
{
case '/':
if(check()) { return false; }
ptr_saved = ptr;
break;
case '\':
if(check()) { return false; }
ptr_saved = ptr;
break;
}
}
auto i = std::ranges::find_if(name, [](auto val) {
return (val >= 0 && val < ' ') || val == '"' || val == '*' || val == ':' || val == '<' || val == '>' || val == '?' || val == '|';
});
if(i != std::end(name)) { return false; }
return true;
}
question from:
https://stackoverflow.com/questions/65873095/rules-for-checking-that-a-filename-is-safe 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…