diff --git a/fast-server/handlers/static_handler.go b/fast-server/handlers/static_handler.go index 61a421f..9ebc22a 100644 --- a/fast-server/handlers/static_handler.go +++ b/fast-server/handlers/static_handler.go @@ -8,10 +8,18 @@ import ( ) func ServeIndexOrFile(c echo.Context, publicDir, requestPath string) error { - fullPath := filepath.Join(publicDir, filepath.Clean(requestPath)) + // Convert publicDir to absolute path + absPublicDir, err := filepath.Abs(publicDir) + if err != nil { + c.Logger().Errorf("Failed to get absolute path for public dir: %v", err) + return echo.ErrInternalServerError + } + + // Clean and join the paths using absolute path + fullPath := filepath.Join(absPublicDir, filepath.Clean(requestPath)) - // Prevent directory traversal - if !strings.HasPrefix(fullPath, publicDir) { + // Double-check for directory traversal using absolute path + if !strings.HasPrefix(fullPath, absPublicDir) { c.Logger().Warnf("Attempted directory traversal detected: %s", fullPath) return echo.ErrNotFound } @@ -22,7 +30,14 @@ func ServeIndexOrFile(c echo.Context, publicDir, requestPath string) error { } // If file doesn't exist or is a directory, serve the root index.html - indexPath := filepath.Join(publicDir, "index.html") + indexPath := filepath.Join(absPublicDir, "index.html") + + // Verify index.html exists + if _, err := os.Stat(indexPath); err != nil { + c.Logger().Errorf("index.html not found at: %s", indexPath) + return echo.ErrNotFound + } + c.Logger().Infof("Serving index.html: %s", indexPath) return c.File(indexPath) } diff --git a/fast-server/test/config.yaml b/fast-server/test/config.yaml index 35330da..ea615f8 100644 --- a/fast-server/test/config.yaml +++ b/fast-server/test/config.yaml @@ -5,14 +5,14 @@ server: domains: - name: domain1.lan type: static - public_dir: test/public/domain1.lan + public_dir: test/www/domain1.lan ssl: cert_file: test/ssl/domain1.lan/fullchain.pem key_file: test/ssl/domain1.lan/privkey.pem - name: domain2.lan type: file_directory - public_dir: test/public/domain2.lan + public_dir: test/www/domain2.lan ssl: cert_file: test/ssl/domain2.lan/fullchain.pem key_file: test/ssl/domain2.lan/privkey.pem