security: require delete permission for HTTP rename overwrite
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user