56 lines
1.2 KiB
Go
56 lines
1.2 KiB
Go
package codexhome
|
|
|
|
import (
|
|
"errors"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
var ErrOutsideCodexHome = errors.New("路径超出 Codex home")
|
|
var ErrForbiddenPath = errors.New("禁止访问敏感路径")
|
|
|
|
func ResolveInside(home string, rel string) (string, error) {
|
|
if filepath.IsAbs(rel) {
|
|
return "", ErrOutsideCodexHome
|
|
}
|
|
cleanHome, err := filepath.Abs(home)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
candidate, err := filepath.Abs(filepath.Join(cleanHome, rel))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
relative, err := filepath.Rel(cleanHome, candidate)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
|
|
return "", ErrOutsideCodexHome
|
|
}
|
|
if IsForbidden(candidate, cleanHome) {
|
|
return "", ErrForbiddenPath
|
|
}
|
|
return candidate, nil
|
|
}
|
|
|
|
func IsForbidden(path string, home string) bool {
|
|
cleanHome, err := filepath.Abs(home)
|
|
if err != nil {
|
|
return true
|
|
}
|
|
cleanPath, err := filepath.Abs(path)
|
|
if err != nil {
|
|
return true
|
|
}
|
|
rel, err := filepath.Rel(cleanHome, cleanPath)
|
|
if err != nil {
|
|
return true
|
|
}
|
|
rel = filepath.ToSlash(rel)
|
|
forbidden := map[string]bool{
|
|
"auth.json": true,
|
|
}
|
|
return forbidden[rel]
|
|
}
|