fix: recursive check

This commit is contained in:
Henrique Dias 2026-06-07 17:12:31 +02:00
parent 67ed670d92
commit 3406d3d7f9
No known key found for this signature in database
6 changed files with 94 additions and 13 deletions

View file

@ -228,10 +228,6 @@ func resourcePatchHandler(fileCache FileCache) handleFunc {
return http.StatusForbidden, nil
}
// Refuse to copy/move through a symlink that escapes the user's scope,
// for either the source (read escape) or the destination (write
// escape). fileutils.Copy/MoveFile operate on the raw afero FS and
// follow symlinks, so they bypass the guards in stat()/writeFile().
for _, p := range []string{src, dst} {
if ok, scopeErr := files.WithinScope(d.user.Fs, p); scopeErr != nil || !ok {
if scopeErr != nil {
@ -308,9 +304,6 @@ func addVersionSuffix(source string, afs afero.Fs) string {
}
func writeFile(afs afero.Fs, dst string, in io.Reader, fileMode, dirMode fs.FileMode) (os.FileInfo, error) {
// Refuse to write through a symlink that escapes the user's scope, so an
// overwrite of an existing escaping symlink cannot modify a file outside
// the boundary.
if ok, err := files.WithinScope(afs, dst); err != nil || !ok {
return nil, os.ErrPermission
}

View file

@ -166,8 +166,7 @@ func tusPatchHandler(cache UploadCache) handleFunc {
if r.Header.Get("Content-Type") != "application/offset+octet-stream" {
return http.StatusUnsupportedMediaType, nil
}
// Defense in depth: refuse to write through a symlink that escapes the
// scope, in case the target path is (or sits behind) an escaping link.
if ok, scopeErr := files.WithinScope(d.user.Fs, r.URL.Path); scopeErr != nil || !ok {
return http.StatusForbidden, nil
}