This commit is contained in:
2026-04-17 11:12:45 +03:00
commit f4b1ac5789
14 changed files with 656 additions and 0 deletions

29
safepath.go Normal file
View File

@@ -0,0 +1,29 @@
package main
import (
"fmt"
"path/filepath"
"strings"
)
// resolveSafe joins p onto root, cleans it, and confirms the result stays
// within root. Rejects absolute paths and anything that escapes via "..".
func resolveSafe(root, p string) (string, error) {
if p == "" {
return "", fmt.Errorf("empty path")
}
if filepath.IsAbs(p) {
return "", fmt.Errorf("absolute paths are not allowed: %s", p)
}
joined := filepath.Join(root, p)
cleaned := filepath.Clean(joined)
rel, err := filepath.Rel(root, cleaned)
if err != nil {
return "", fmt.Errorf("cannot resolve %q: %w", p, err)
}
if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
return "", fmt.Errorf("path escapes project root: %s", p)
}
return cleaned, nil
}