From e7139a9dc91680b6215d5493b81cfa47885ddb6b Mon Sep 17 00:00:00 2001 From: "Victor B." Date: Mon, 25 Mar 2024 15:49:34 +0100 Subject: [PATCH] Enforce the egg's file denylist more thoroughly Closes pterodactyl/panel#5042 --- router/router_download.go | 5 +++++ router/router_server_files.go | 12 ++++++++++++ server/filesystem/compress.go | 5 +++++ sftp/handler.go | 11 +++++++++++ 4 files changed, 33 insertions(+) diff --git a/router/router_download.go b/router/router_download.go index 178484d..ef7a5cf 100644 --- a/router/router_download.go +++ b/router/router_download.go @@ -78,6 +78,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 e44afbe..1adb7bc 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,6 +331,11 @@ func postServerPullRemoteFile(c *gin.Context) { 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 1ac192c..260cb95 100644 --- a/server/filesystem/compress.go +++ b/server/filesystem/compress.go @@ -28,6 +28,11 @@ 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) { + for _, file := range paths { + if err := fs.IsIgnored(path.Join(dir, file)); err != nil { + return nil, err + } + } a := &Archive{Filesystem: fs, BaseDirectory: dir, Files: paths} d := path.Join( dir, diff --git a/sftp/handler.go b/sftp/handler.go index 74ba9eb..b9ab6ee 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.