From 29fa31370a3e45ac8013bacff6171179a4df6e35 Mon Sep 17 00:00:00 2001 From: Quinten <67589015+QuintenQVD0@users.noreply.github.com> Date: Sat, 28 Sep 2024 00:11:53 +0200 Subject: [PATCH] Enforce the egg's file denylist more thoroughly (#29) * draft: Enforce the egg's file denylist more thoroughly * feat: Skip ignored files during compression instead of stopping with an error * Fix: Skip ignored files in CompressFiles --- router/router_download.go | 5 +++++ router/router_server_files.go | 12 +++++++++++- server/filesystem/compress.go | 14 +++++++++++++- sftp/handler.go | 11 +++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/router/router_download.go b/router/router_download.go index b1ca5a0a..7d070a81 100644 --- a/router/router_download.go +++ b/router/router_download.go @@ -89,6 +89,11 @@ func getDownloadFile(c *gin.Context) { return } + if err := s.Filesystem().IsIgnored(token.FilePath); err != nil { + middleware.CaptureAndAbort(c, err) + return + } + f, st, err := s.Filesystem().File(token.FilePath) if err != nil { middleware.CaptureAndAbort(c, err) diff --git a/router/router_server_files.go b/router/router_server_files.go index ad6dd0c8..5d3ba78d 100644 --- a/router/router_server_files.go +++ b/router/router_server_files.go @@ -31,6 +31,10 @@ import ( func getServerFileContents(c *gin.Context) { s := middleware.ExtractServer(c) p := strings.TrimLeft(c.Query("file"), "/") + if err := s.Filesystem().IsIgnored(p); err != nil { + middleware.CaptureAndAbort(c, err) + return + } f, st, err := s.Filesystem().File(p) if err != nil { middleware.CaptureAndAbort(c, err) @@ -214,6 +218,9 @@ func postServerDeleteFiles(c *gin.Context) { case <-ctx.Done(): return ctx.Err() default: + if err := s.Filesystem().IsIgnored(pi); err != nil { + return err + } return s.Filesystem().Delete(pi) } }) @@ -324,7 +331,10 @@ func postServerPullRemoteFile(c *gin.Context) { FileName: data.FileName, UseHeader: data.UseHeader, }) - + if err := s.Filesystem().IsIgnored(dl.Path()); err != nil { + middleware.CaptureAndAbort(c, err) + return + } download := func() error { s.Log().WithField("download_id", dl.Identifier).WithField("url", u.String()).Info("starting pull of remote file to disk") if err := dl.Execute(); err != nil { diff --git a/server/filesystem/compress.go b/server/filesystem/compress.go index 15f2d26e..efb8e11a 100644 --- a/server/filesystem/compress.go +++ b/server/filesystem/compress.go @@ -29,7 +29,19 @@ import ( // and the compressed file will be placed at that location named // `archive-{date}.tar.gz`. func (fs *Filesystem) CompressFiles(dir string, paths []string) (ufs.FileInfo, error) { - a := &Archive{Filesystem: fs, BaseDirectory: dir, Files: paths} + var validPaths []string + for _, file := range paths { + if err := fs.IsIgnored(path.Join(dir, file)); err == nil { + validPaths = append(validPaths, file) + } + } + + // If there are no valid paths, return an error + if len(validPaths) == 0 { + return nil, fmt.Errorf("no valid files to compress") + } + + a := &Archive{Filesystem: fs, BaseDirectory: dir, Files: validPaths} d := path.Join( dir, fmt.Sprintf("archive-%s.tar.gz", strings.ReplaceAll(time.Now().Format(time.RFC3339), ":", "")), diff --git a/sftp/handler.go b/sftp/handler.go index dacea401..aed12dbc 100644 --- a/sftp/handler.go +++ b/sftp/handler.go @@ -79,6 +79,9 @@ func (h *Handler) Fileread(request *sftp.Request) (io.ReaderAt, error) { } h.mu.Lock() defer h.mu.Unlock() + if err := h.fs.IsIgnored(request.Filepath); err != nil { + return nil, err + } f, _, err := h.fs.File(request.Filepath) if err != nil { if !errors.Is(err, os.ErrNotExist) { @@ -104,6 +107,10 @@ func (h *Handler) Filewrite(request *sftp.Request) (io.WriterAt, error) { h.mu.Lock() defer h.mu.Unlock() + + if err := h.fs.IsIgnored(request.Filepath); err != nil { + return nil, err + } // The specific permission required to perform this action. If the file exists on the // system already it only needs to be an update, otherwise we'll check for a create. permission := PermissionFileUpdate @@ -148,6 +155,10 @@ func (h *Handler) Filecmd(request *sftp.Request) error { l = l.WithField("target", request.Target) } + if err := h.fs.IsIgnored(request.Filepath); err != nil { + return err + } + switch request.Method { // Allows a user to make changes to the permissions of a given file or directory // on their server using their SFTP client.