From 6881041c3ea254b5b3e434cedf71f4ae4746831a Mon Sep 17 00:00:00 2001 From: HynoR <20227709+HynoR@users.noreply.github.com> Date: Sun, 30 Nov 2025 11:02:08 +0800 Subject: [PATCH 1/2] feat: Add path protection mechanism to prevent deletion of critical system directories --- agent/utils/files/file_op.go | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/agent/utils/files/file_op.go b/agent/utils/files/file_op.go index a5728944ae0f..5698ebd060cb 100644 --- a/agent/utils/files/file_op.go +++ b/agent/utils/files/file_op.go @@ -33,6 +33,40 @@ import ( "github.com/spf13/afero" ) +var protectedPaths = []string{ + "/", + "/bin", + "/sbin", + "/etc", + "/boot", + "/usr", + "/lib", + "/lib64", + "/dev", + "/proc", + "/sys", + "/root", +} + +func isProtected(path string) bool { + real, err := filepath.EvalSymlinks(path) + if err == nil { + path = real + } + + abs, err := filepath.Abs(path) + if err == nil { + path = abs + } + + for _, p := range protectedPaths { + if path == p || strings.HasPrefix(path, p+"/") { + return true + } + } + return false +} + type FileOp struct { Fs afero.Fs } @@ -104,6 +138,9 @@ func (f FileOp) LinkFile(source string, dst string, isSymlink bool) error { } func (f FileOp) DeleteDir(dst string) error { + if isProtected(dst) { + return buserr.New("ErrPathNotDelete") + } return f.Fs.RemoveAll(dst) } @@ -113,14 +150,23 @@ func (f FileOp) Stat(dst string) bool { } func (f FileOp) DeleteFile(dst string) error { + if isProtected(dst) { + return buserr.New("ErrPathNotDelete") + } return f.Fs.Remove(dst) } func (f FileOp) CleanDir(dst string) error { + if isProtected(dst) { + return buserr.New("ErrPathNotDelete") + } return cmd.RunDefaultBashCf("rm -rf %s/*", dst) } func (f FileOp) RmRf(dst string) error { + if isProtected(dst) { + return buserr.New("ErrPathNotDelete") + } return cmd.RunDefaultBashCf("rm -rf %s", dst) } From f7676854774652a87c6f69133e39c00c5e807c2e Mon Sep 17 00:00:00 2001 From: HynoR <20227709+HynoR@users.noreply.github.com> Date: Sun, 30 Nov 2025 11:29:18 +0800 Subject: [PATCH 2/2] feat: Enhance recycle bin service with path protection for deletion requests --- agent/app/service/recycle_bin.go | 3 +++ agent/utils/files/file_op.go | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/agent/app/service/recycle_bin.go b/agent/app/service/recycle_bin.go index efcbb2e23d76..9af3559e293c 100644 --- a/agent/app/service/recycle_bin.go +++ b/agent/app/service/recycle_bin.go @@ -76,6 +76,9 @@ func (r RecycleBinService) Page(search dto.PageInfo) (int64, []response.RecycleB } func (r RecycleBinService) Create(create request.RecycleBinCreate) error { + if files.IsProtected(create.SourcePath) { + return buserr.New("ErrPathNotDelete") + } op := files.NewFileOp() if !op.Stat(create.SourcePath) { return buserr.New("ErrLinkPathNotFound") diff --git a/agent/utils/files/file_op.go b/agent/utils/files/file_op.go index 5698ebd060cb..5bd8aa48b858 100644 --- a/agent/utils/files/file_op.go +++ b/agent/utils/files/file_op.go @@ -48,7 +48,7 @@ var protectedPaths = []string{ "/root", } -func isProtected(path string) bool { +func IsProtected(path string) bool { real, err := filepath.EvalSymlinks(path) if err == nil { path = real @@ -60,7 +60,7 @@ func isProtected(path string) bool { } for _, p := range protectedPaths { - if path == p || strings.HasPrefix(path, p+"/") { + if path == p { return true } } @@ -138,7 +138,7 @@ func (f FileOp) LinkFile(source string, dst string, isSymlink bool) error { } func (f FileOp) DeleteDir(dst string) error { - if isProtected(dst) { + if IsProtected(dst) { return buserr.New("ErrPathNotDelete") } return f.Fs.RemoveAll(dst) @@ -150,21 +150,21 @@ func (f FileOp) Stat(dst string) bool { } func (f FileOp) DeleteFile(dst string) error { - if isProtected(dst) { + if IsProtected(dst) { return buserr.New("ErrPathNotDelete") } return f.Fs.Remove(dst) } func (f FileOp) CleanDir(dst string) error { - if isProtected(dst) { + if IsProtected(dst) { return buserr.New("ErrPathNotDelete") } return cmd.RunDefaultBashCf("rm -rf %s/*", dst) } func (f FileOp) RmRf(dst string) error { - if isProtected(dst) { + if IsProtected(dst) { return buserr.New("ErrPathNotDelete") } return cmd.RunDefaultBashCf("rm -rf %s", dst)