From 4bf6cb41990e16b1d99015aea080d06d7ef1152d Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Tue, 18 Oct 2022 21:55:25 -0600 Subject: 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 --- modules/caddyhttp/caddyhttp_test.go | 2 +- modules/caddyhttp/fileserver/staticfiles.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'modules') diff --git a/modules/caddyhttp/caddyhttp_test.go b/modules/caddyhttp/caddyhttp_test.go index 1bca4d6..a14de78 100644 --- a/modules/caddyhttp/caddyhttp_test.go +++ b/modules/caddyhttp/caddyhttp_test.go @@ -87,7 +87,7 @@ func TestSanitizedPathJoin(t *testing.T) { } actual := SanitizedPathJoin(tc.inputRoot, u.Path) if actual != tc.expect { - t.Errorf("Test %d: SanitizedPathJoin('%s', '%s') => %s (expected '%s')", + t.Errorf("Test %d: SanitizedPathJoin('%s', '%s') => '%s' (expected '%s')", i, tc.inputRoot, tc.inputPath, actual, tc.expect) } } diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index 04728ce..fe1a4fc 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -26,6 +26,7 @@ import ( "os" "path" "path/filepath" + "runtime" "strconv" "strings" "time" @@ -232,6 +233,19 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error { func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer) + if runtime.GOOS == "windows" { + // reject paths with Alternate Data Streams (ADS) + if strings.Contains(r.URL.Path, ":") { + return caddyhttp.Error(http.StatusBadRequest, fmt.Errorf("illegal ADS path")) + } + // reject paths with "8.3" short names + trimmedPath := strings.TrimRight(r.URL.Path, ". ") // Windows ignores trailing dots and spaces, sigh + if len(path.Base(trimmedPath)) <= 12 && strings.Contains(trimmedPath, "~") { + return caddyhttp.Error(http.StatusBadRequest, fmt.Errorf("illegal short name")) + } + // both of those could bypass file hiding or possibly leak information even if the file is not hidden + } + filesToHide := fsrv.transformHidePaths(repl) root := repl.ReplaceAll(fsrv.Root, ".") -- cgit v1.2.3