fix: confine download names to the selected directory (#14345)

This commit is contained in:
蘭
2026-11-08 22:40:02 +08:00
committed by GitHub
parent 51a8156845
commit ab90f4bc2d
3 changed files with 48 additions and 5 deletions
+5 -1
View File
@@ -907,6 +907,10 @@ func (f *FileService) ChangeName(req request.FileRename) error {
func (f *FileService) Wget(w request.FileWget) (string, error) {
fo := files.NewFileOp()
destination, err := files.ResolveDownloadDestination(w.Path, w.Name)
if err != nil {
return "", err
}
key := "file-wget-" + common.GetUuid()
options := files.DownloadOptions{
IgnoreCertificate: w.IgnoreCertificate,
@@ -925,7 +929,7 @@ func (f *FileService) Wget(w request.FileWget) (string, error) {
Password: systemProxy.Password,
}
}
return key, fo.DownloadFileWithProcess(w.Url, filepath.Join(w.Path, w.Name), key, options)
return key, fo.DownloadFileWithProcess(w.Url, destination, key, options)
}
func logFileTaskSources(t *task.Task, sources []string) {
+42
View File
@@ -0,0 +1,42 @@
package files
import (
"os"
"path/filepath"
"strings"
"unicode"
"unicode/utf8"
"github.com/1Panel-dev/1Panel/agent/buserr"
)
func validDownloadFilename(name string) bool {
return strings.TrimSpace(name) != "" && name != "." && name != ".." && len(name) <= 255 && utf8.ValidString(name) &&
!strings.ContainsAny(name, "/\\:") && strings.IndexFunc(name, unicode.IsControl) < 0
}
func ResolveDownloadDestination(directory, name string) (string, error) {
if strings.TrimSpace(directory) == "" || !validDownloadFilename(name) {
return "", buserr.New("ErrInvalidParams")
}
parent, err := filepath.EvalSymlinks(directory)
if err != nil {
return "", err
}
parent, err = filepath.Abs(parent)
if err != nil {
return "", err
}
info, err := os.Stat(parent)
if err != nil {
return "", err
}
if !info.IsDir() {
return "", buserr.New("ErrInvalidParams")
}
destination := filepath.Join(parent, name)
if filepath.Dir(destination) != parent {
return "", buserr.New("ErrInvalidParams")
}
return destination, nil
}
+1 -4
View File
@@ -29,8 +29,6 @@ import (
"sync"
"syscall"
"time"
"unicode"
"unicode/utf8"
"github.com/1Panel-dev/1Panel/agent/buserr"
@@ -399,8 +397,7 @@ func downloadResponseFilename(header string) string {
return ""
}
name := strings.TrimSpace(params["filename"])
if name == "" || name == "." || name == ".." || len(name) > 255 || !utf8.ValidString(name) ||
strings.ContainsAny(name, "/\\:") || strings.IndexFunc(name, unicode.IsControl) >= 0 {
if !validDownloadFilename(name) {
return ""
}
return name