httpsrv: a dot-dot segment of a path refused, with either separator

A path ending in a backslashed dot-dot, or carrying one in a form the
checks did not name, was taken as it stood. Any dot-dot segment is now
refused wherever it is and whichever separator carries it, and a path
ending in a bare dot of either kind.
This commit is contained in:
Vladimir Dubrovin 2026-11-08 14:39:50 +03:00
parent a7e5a8b48b
commit c0eb7a65c6

View File

@ -428,11 +428,12 @@ static int targetunsafe(const char *path)
#endif #endif
} }
if(!strncmp(path, "./", 2) || !strncmp(path, "../", 3)) return 1; if(!strncmp(path, "./", 2) || !strncmp(path, "../", 3)) return 1;
if(strstr(path, "/./") || strstr(path, "/../")) return 1; /* a dot-dot segment, with either separator, wherever it is in the
if(strstr(path, "\\.\\") || strstr(path, "\\..\\")) return 1; path: a walk out of the tree, or a file named to look like one */
if(strstr(path, "/..") || strstr(path, "\\..")) return 1;
if(strstr(path, "/./") || strstr(path, "\\.\\")) return 1;
p = path + strlen(path); p = path + strlen(path);
if(p - path >= 2 && !strcmp(p - 2, "/.")) return 1; if(p - path >= 2 && (!strcmp(p - 2, "/.") || !strcmp(p - 2, "\\."))) return 1;
if(p - path >= 3 && !strcmp(p - 3, "/..")) return 1;
return 0; return 0;
} }