@marcel91200 / caddy Mirror · read-only / commits / 4bf6cb41
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 09:15 UTC

fileserver: Reject ADS and short name paths; trim trailing dots and spaces on Windows (#5148)

* fileserver: Reject ADS and short name paths * caddyhttp: Trim trailing space and dot on Windows Windows ignores trailing dots and spaces in filenames. * Fix test * Adjust path filters * Revert Windows test * Actually revert the test * Just check for colons

Matt Holt committed Oct 18, 2022 at 21:55 UTC 4bf6cb41990e16b1d99015aea080d06d7ef1152d
2 files changed +15 -1
modules/caddyhttp/caddyhttp_test.go
+1 -1
@@ -87,7 +87,7 @@ func TestSanitizedPathJoin(t *testing.T) {
87 }
88 actual := SanitizedPathJoin(tc.inputRoot, u.Path)
89 if actual != tc.expect {
90 - t.Errorf("Test %d: SanitizedPathJoin('%s', '%s') => %s (expected '%s')",
90 + t.Errorf("Test %d: SanitizedPathJoin('%s', '%s') => '%s' (expected '%s')",
91 i, tc.inputRoot, tc.inputPath, actual, tc.expect)
92 }
93 }
modules/caddyhttp/fileserver/staticfiles.go
+14
@@ -26,6 +26,7 @@ import (
26 "os"
27 "path"
28 "path/filepath"
29 + "runtime"
30 "strconv"
31 "strings"
32 "time"
@@ -232,6 +233,19 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error {
233 func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
234 repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
235
236 + if runtime.GOOS == "windows" {
237 + // reject paths with Alternate Data Streams (ADS)
238 + if strings.Contains(r.URL.Path, ":") {
239 + return caddyhttp.Error(http.StatusBadRequest, fmt.Errorf("illegal ADS path"))
240 + }
241 + // reject paths with "8.3" short names
242 + trimmedPath := strings.TrimRight(r.URL.Path, ". ") // Windows ignores trailing dots and spaces, sigh
243 + if len(path.Base(trimmedPath)) <= 12 && strings.Contains(trimmedPath, "~") {
244 + return caddyhttp.Error(http.StatusBadRequest, fmt.Errorf("illegal short name"))
245 + }
246 + // both of those could bypass file hiding or possibly leak information even if the file is not hidden
247 + }
248 +
249 filesToHide := fsrv.transformHidePaths(repl)
250
251 root := repl.ReplaceAll(fsrv.Root, ".")