security: require delete permission for HTTP rename overwrite

This commit is contained in:
OpenClaw Agent
2026-09-21 21:19:55 +08:00
parent a9c1ab031b
commit 3d865259fc
+35
View File
@@ -263,6 +263,30 @@ func (s *Server) newdir(w http.ResponseWriter, r *http.Request) {
s.logOp(r, fmt.Sprintf("created directory '%s'", p))
writeCreated(w)
}
func checkDeleteTree(store storage.Storage, a *auth.Account, root string) error {
info, err := store.Stat(root)
if err != nil {
return err
}
if !a.MaskFor(root).HasDelete() {
return fmt.Errorf("delete permission denied")
}
if !info.IsDir() {
return nil
}
items, err := store.List(root)
if err != nil {
return err
}
for _, item := range items {
p := path.Join(root, item.Name())
if err := checkDeleteTree(store, a, p); err != nil {
return err
}
}
return nil
}
func (s *Server) rename(w http.ResponseWriter, r *http.Request) {
a := account(r, s)
rawOld, rawNew := r.FormValue("old"), r.FormValue("new")
@@ -276,6 +300,17 @@ func (s *Server) rename(w http.ResponseWriter, r *http.Request) {
writeJSONError(w, http.StatusForbidden, "has no privilege")
return
}
if old != neu {
if _, e := s.Store.Stat(neu); e == nil {
if e := checkDeleteTree(s.Store, a, neu); e != nil {
writeJSONError(w, http.StatusForbidden, "has no privilege")
return
}
} else if !os.IsNotExist(e) {
http.Error(w, e.Error(), 500)
return
}
}
if e := s.Store.Rename(old, neu); e != nil {
http.Error(w, e.Error(), 500)
return