fix: check path for OoS symlinks
							parent
							
								
									094ee331d6
								
							
						
					
					
						commit
						592606a00d
					
				|  | @ -65,21 +65,6 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) { | |||
| 		return nil, os.ErrPermission | ||||
| 	} | ||||
| 
 | ||||
| 	isSymlink := false | ||||
| 	symlink := "" | ||||
| 	if lst, ok := opts.Fs.(afero.Lstater); ok { | ||||
| 		info, _, err := lst.LstatIfPossible(opts.Path) | ||||
| 		if err == nil { | ||||
| 			isSymlink = IsSymlink(info.Mode()) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if isSymlink { | ||||
| 		if lsf, ok := opts.Fs.(afero.LinkReader); ok { | ||||
| 			symlink, _ = lsf.ReadlinkIfPossible(opts.Path) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	info, err := opts.Fs.Stat(opts.Path) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|  | @ -92,8 +77,6 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) { | |||
| 		ModTime:   info.ModTime(), | ||||
| 		Mode:      info.Mode(), | ||||
| 		IsDir:     info.IsDir(), | ||||
| 		IsSymlink: isSymlink, | ||||
| 		Link:      symlink, | ||||
| 		Size:      info.Size(), | ||||
| 		Extension: filepath.Ext(info.Name()), | ||||
| 		Token:     opts.Token, | ||||
|  |  | |||
|  | @ -37,15 +37,9 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d | |||
| 		return errToStatus(err), err | ||||
| 	} | ||||
| 
 | ||||
| 	// check if symlink's target is within base path
 | ||||
| 	if file.IsSymlink { | ||||
| 		parentDir := filepath.Dir(filepath.Clean(file.Path)) | ||||
| 		fullLinkTarget := filepath.Join(d.user.FullPath(parentDir), file.Link) | ||||
| 		scopedLinkTarget := d.user.FullPath(filepath.Join(parentDir, file.Link)) | ||||
| 		if fullLinkTarget != scopedLinkTarget { | ||||
| 			err = errors.ErrNotExist | ||||
| 			return errToStatus(err), err | ||||
| 		} | ||||
| 	err = checkOutOfScopeSymlink(d, file.Path) | ||||
| 	if err != nil { | ||||
| 		return errToStatus(err), err | ||||
| 	} | ||||
| 
 | ||||
| 	if r.URL.Query().Get("disk_usage") == "true" { | ||||
|  | @ -322,6 +316,38 @@ func checkParent(src, dst string) error { | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Checks if path contains symlink to out-of-scope targets.
 | ||||
| // Returns error ErrNotExist if it does.
 | ||||
| func checkOutOfScopeSymlink(d *data, path string) error { | ||||
| 	lsf, ok := d.user.Fs.(afero.LinkReader) | ||||
| 	if !ok { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	var parts []string | ||||
| 	for _, part := range strings.Split(path, string(os.PathSeparator)) { | ||||
| 		if part != "" { | ||||
| 			parts = append(parts, part) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	evalPath := string(os.PathSeparator) | ||||
| 	for _, part := range parts { | ||||
| 		evalPath = filepath.Join(evalPath, filepath.Clean(part)) | ||||
| 		symlink, err := lsf.ReadlinkIfPossible(evalPath) | ||||
| 		if err == nil { | ||||
| 			parentDir := filepath.Dir(evalPath) | ||||
| 			fullLinkTarget := filepath.Join(d.user.FullPath(parentDir), symlink) | ||||
| 			scopedLinkTarget := d.user.FullPath(filepath.Join(parentDir, symlink)) | ||||
| 			if fullLinkTarget != scopedLinkTarget { | ||||
| 				return errors.ErrNotExist | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func addVersionSuffix(source string, fs afero.Fs) string { | ||||
| 	counter := 1 | ||||
| 	dir, name := path.Split(source) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Laurynas Gadliauskas
						Laurynas Gadliauskas