You're on your own there.
The rest of the world, from https://owasp.org/www-community/attacks/Path_Traversal to CVE-2023-34096 through many other places along the way, calls this an attack.
You're trying to defend a bad implementation strategy based upon an erroneously perceived need for something that the world does not do. And somehow trying to make it Daniel J. Bernstein's fault for showing how to quite simply address the problem without reinventing wheels badly.
No. We're having this discussion because of the right things to learn; which is to let the filesystem do the name lookup of filesystem-like pathnames, to not reinvent that, and to prevent attacks of things like /../ and non-regular files.
/../ is not a "pattern" that can be relied upon when it reaches a server. It is an attack.
RFC 3986 explains how it is normalized away by clients, before server involvement.
Read what the SECURITY section says about dots again. M. Bernstein thought of all this. It also implements the Unix file hiding convention.
Existence says otherwise. It can be and is in #publicfile. Read the manual pages that I pointed to to see how it works.
Yes, one also has to take advantage of *all* that the operating system has to offer when it comes to pathname lookup. (-:
Bernstein #publicfile changes root to the content root directory and drops privileges. .. in URLs simply wouldn't escape, because the operating system's own name lookup wouldn't let them. There's no way for you to construct a URL that will get you my server's /etc/passwd , for example.
http://cr.yp.to/publicfile/httpd.html
http://jdebp.info/Softwares/djbwares/guide/commands/httpd.xml
I use #publicfile which relies upon the filesystem entirely, apart from an injection prevention mechanism that disallows dots at the starts of pathname components.
Symbolic links have been doing the job of host aliases for many years for me.
$ ls -dg /public/file/jdebp.uk
lrwxr-xr-x 1 wheel 10 Aug 1 2018 /public/file/jdebp.uk -> jdebp.info
$
It's entirely backwards to think that eliminating the filesystem is the lesson to learn here.
The lesson to learn here is that if one is presenting hierarchical CIS URLs then one should parse them like filesystem pathnames are parsed. /imgsomething must not ever be matched by /img in pathname lookup.
The best way to achieve this is not to re-invent filesystem pathname parsing badly yet again, but to let the filesystem parse the pathnames.
By the way, this GOPHER site has quietly sat unattended since before COVID-19. I've no reason to think that it's not still running fine. The software is stable, and the HTTP site that runs in parallel is fine. But I still need to get back in touch with the hosting provider, whom lockdowns and other factors cut me off from.
It was more a case of making sure that a niche was filled. Daniel J. Bernstein years ago wrote a server package that served up entirely static sites over HTTP and FTP using UCSPI-TCP server programs. I added a UCSPI-TCP server that similarly served up an entirely static #GOPHER site.
http://jdebp.info/Softwares/djbwares/
I couldn't tell you much about the rest of the GOPHER universe. But since my site isn't listed on any directory that I know of ... (-:
That's a straw man, though, because it was even in the original Bernstein doco that publicfile didn't read directories for security.
Always read the manual. (-:
On the contrary: HTTP/1.1 support, including persistent connections, was even in the Bernstein original, as was checking that the pathname was not a directory.
http://jdebp.info/Softwares/djbwares/guide/commands/httpd.xml
I haven't looked at the code of Bernstein's publicfile in a while, but I don't remember offhand any obvious problems with metadata race conditions.