Rewritten FS paths were only checked for the "/../" substring, which
allowed leading "../" values to bypass the traversal guard.
Reject any rewritten path containing a ".." path segment before joining
it with FS.Root. This closes the PathRewrite/NewPathPrefixStripper escape
in the default OS-backed handler and keeps rewritten paths within the
intended static root.
This vulnerability was discovered and reported by bugbunny.ai
ServeFile and ServeFS interpret the path as a URI, so percent-encoded
sequences are decoded and characters like '?' and '#' act as URI
delimiters. This makes it impossible to serve files whose names
contain those characters.
Changing this behavior would be backwards incompatible. So instead the
new ServeFileLiteral, ServeFSLiteral and SendFileLiteral are added.
The new Literal variants percent-encode the path before setting it as
the request URI, preserving every byte of the original filesystem path.
Thanks to @thesmartshadow for reporting this issue.
- Apply `fs.Root` in non-`os.FS` path resolution.
- Normalize `fs.FS` roots (`./`, trailing slash, leading slash, separators).
- Handle `PathRewrite` outputs without a leading slash.
- Add tests for `MapFS` and `DirFS` root enforcement.
* substitute *os.File by fs.File
* refactor error handling by using the new recommended form
* finish implementation
* substitute seek(offset,0) by seek(offset, io.SeekStart)
* add unit test
* use io.SeekStart on Seek method