Skip to content

Commit 566329d

Browse files
committed
fix(webdav): escape LIKE patterns, check dstDir is dir, bound PROPFIND body
Signed-off-by: Lythen <[email protected]>
1 parent 900f6eb commit 566329d

3 files changed

Lines changed: 20 additions & 11 deletions

File tree

server/webdav/file.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,13 @@ func moveFiles(ctx context.Context, src, dst string, overwrite bool) (status int
5555
if !common.CanWrite(user, srcMeta, srcDir) || !common.CanWrite(user, dstMeta, dstDir) {
5656
return http.StatusForbidden, nil
5757
}
58-
if _, err = fs.Get(ctx, dstDir, &fs.GetArgs{}); err != nil {
58+
if dstDirInfo, err := fs.Get(ctx, dstDir, &fs.GetArgs{}); err != nil {
5959
if errs.IsObjectNotFound(err) {
6060
return http.StatusConflict, err
6161
}
6262
return http.StatusMethodNotAllowed, err
63+
} else if !dstDirInfo.IsDir() {
64+
return http.StatusConflict, nil
6365
}
6466
dstExisted := false
6567
if _, err = fs.Get(ctx, dst, &fs.GetArgs{}); err == nil {
@@ -119,11 +121,13 @@ func copyFiles(ctx context.Context, src, dst string, overwrite bool) (status int
119121
if !common.CanWrite(user, dstMeta, dstDir) {
120122
return http.StatusForbidden, nil
121123
}
122-
if _, err = fs.Get(ctx, dstDir, &fs.GetArgs{}); err != nil {
124+
if dstDirInfo, err := fs.Get(ctx, dstDir, &fs.GetArgs{}); err != nil {
123125
if errs.IsObjectNotFound(err) {
124126
return http.StatusConflict, err
125127
}
126128
return http.StatusMethodNotAllowed, err
129+
} else if !dstDirInfo.IsDir() {
130+
return http.StatusConflict, nil
127131
}
128132
dstExisted := false
129133
if _, err = fs.Get(ctx, dst, &fs.GetArgs{}); err == nil {

server/webdav/prop.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -352,24 +352,22 @@ func moveDeadProps(src, dst string) error {
352352
return errors.New("webdav property database is not initialized")
353353
}
354354
return database.Transaction(func(tx *gorm.DB) error {
355+
escaped := strings.ReplaceAll(strings.ReplaceAll(src, "%", "\\%"), "_", "\\_")
356+
if err := tx.Where("path = ? OR path LIKE ? ESCAPE '\\'", src, escaped+"/%").Delete(&model.WebDAVProperty{}).Error; err != nil {
357+
return err
358+
}
355359
var rows []model.WebDAVProperty
356-
if err := tx.Where("path = ? OR path LIKE ?", src, src+"/%").Find(&rows).Error; err != nil {
360+
if err := tx.Where("path = ? OR path LIKE ? ESCAPE '\\'", src, escaped+"/%").Find(&rows).Error; err != nil {
357361
return err
358362
}
359363
for _, row := range rows {
360364
newPath := dst + strings.TrimPrefix(row.Path, src)
361-
if err := tx.Where("path = ? AND namespace = ? AND name = ?", newPath, row.Namespace, row.Name).Delete(&model.WebDAVProperty{}).Error; err != nil {
362-
return err
363-
}
364365
copy := row
365366
copy.ID = 0
366367
copy.Path = newPath
367368
if err := tx.Create(&copy).Error; err != nil {
368369
return err
369370
}
370-
if err := tx.Delete(&row).Error; err != nil {
371-
return err
372-
}
373371
}
374372
return nil
375373
})

server/webdav/xml.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,20 @@ type propfind struct {
178178
}
179179

180180
func readPropfind(r io.Reader) (pf propfind, status int, err error) {
181-
body, err := io.ReadAll(r)
181+
// 64KB is more than enough for a well-formed PROPFIND body.
182+
const maxBody = 64 << 10
183+
body, err := io.ReadAll(io.LimitReader(r, maxBody))
182184
if err != nil {
183185
return propfind{}, http.StatusBadRequest, err
184186
}
187+
// If the limit was reached, the body was too large.
188+
if len(body) >= maxBody {
189+
// Drain any remaining bytes so the connection stays usable.
190+
_, _ = io.Copy(io.Discard, r)
191+
return propfind{}, http.StatusRequestEntityTooLarge, nil
192+
}
185193
if len(body) == 0 {
186194
// An empty body means to propfind allprop.
187-
// http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND
188195
return propfind{Allprop: new(struct{})}, 0, nil
189196
}
190197
if hasEmptyNamespacePrefix(body) {

0 commit comments

Comments
 (0)