Skip to content

Commit bba4fb2

Browse files
hshpyj2rong4cn
andauthored
fix(security): directory traversal (#744)
* fix(security): Directory traversal * chore: . * 优化 --------- Co-authored-by: j2rong4cn <[email protected]>
1 parent a20c202 commit bba4fb2

File tree

4 files changed

+27
-15
lines changed

4 files changed

+27
-15
lines changed

internal/errs/errors.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
var (
1111
NotImplement = errors.New("not implement")
1212
NotSupport = errors.New("not support")
13-
RelativePath = errors.New("access using relative path is not allowed")
13+
RelativePath = errors.New("using relative path is not allowed")
1414

1515
MoveBetweenTwoStorages = errors.New("can't move files between two storages, try to copy")
1616
UploadNotSupported = errors.New("upload not supported")

pkg/utils/path.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,20 @@ func EncodePath(path string, all ...bool) string {
7575
}
7676

7777
func JoinBasePath(basePath, reqPath string) (string, error) {
78-
/** relative path:
79-
* 1. ..
80-
* 2. ../
81-
* 3. /..
82-
* 4. /../
83-
* 5. /a/b/..
84-
*/
85-
if reqPath == ".." ||
86-
strings.HasSuffix(reqPath, "/..") ||
87-
strings.HasPrefix(reqPath, "../") ||
88-
strings.Contains(reqPath, "/../") {
78+
reqPath, err := CheckRelativePath(reqPath)
79+
if err != nil {
80+
return "", err
81+
}
82+
return stdpath.Join(FixAndCleanPath(basePath), reqPath), nil
83+
}
84+
85+
func CheckRelativePath(path string) (string, error) {
86+
isRelativePath := strings.Contains(path, "..")
87+
path = FixAndCleanPath(path)
88+
if isRelativePath && !strings.Contains(path, "..") {
8989
return "", errs.RelativePath
9090
}
91-
return stdpath.Join(FixAndCleanPath(basePath), FixAndCleanPath(reqPath)), nil
91+
return path, nil
9292
}
9393

9494
func GetFullPath(mountPath, path string) string {

server/handles/fsbatch.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/OpenListTeam/OpenList/v4/internal/model"
1212
"github.com/OpenListTeam/OpenList/v4/internal/op"
1313
"github.com/OpenListTeam/OpenList/v4/pkg/generic"
14+
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
1415
"github.com/OpenListTeam/OpenList/v4/server/common"
1516
"github.com/gin-gonic/gin"
1617
"github.com/pkg/errors"
@@ -173,6 +174,11 @@ func FsBatchRename(c *gin.Context) {
173174
if renameObject.SrcName == "" || renameObject.NewName == "" {
174175
continue
175176
}
177+
renameObject.NewName, err = utils.CheckRelativePath(renameObject.NewName)
178+
if err != nil {
179+
common.ErrorResp(c, err, 403)
180+
return
181+
}
176182
filePath := fmt.Sprintf("%s/%s", reqPath, renameObject.SrcName)
177183
if err := fs.Rename(c.Request.Context(), filePath, renameObject.NewName); err != nil {
178184
common.ErrorResp(c, err, 500)
@@ -228,10 +234,13 @@ func FsRegexRename(c *gin.Context) {
228234
}
229235

230236
for _, file := range files {
231-
232237
if srcRegexp.MatchString(file.GetName()) {
238+
newFileName, err := utils.CheckRelativePath(srcRegexp.ReplaceAllString(file.GetName(), req.NewNameRegex))
239+
if err != nil {
240+
common.ErrorResp(c, err, 403)
241+
return
242+
}
233243
filePath := fmt.Sprintf("%s/%s", reqPath, file.GetName())
234-
newFileName := srcRegexp.ReplaceAllString(file.GetName(), req.NewNameRegex)
235244
if err := fs.Rename(c.Request.Context(), filePath, newFileName); err != nil {
236245
common.ErrorResp(c, err, 500)
237246
return

server/handles/fsmanage.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ func FsRename(c *gin.Context) {
204204
return
205205
}
206206
reqPath, err := user.JoinPath(req.Path)
207+
if err == nil {
208+
req.Name, err = utils.CheckRelativePath(req.Name)
209+
}
207210
if err != nil {
208211
common.ErrorResp(c, err, 403)
209212
return

0 commit comments

Comments
 (0)