fix: harden thothctl file access

This commit is contained in:
2026-08-04 17:34:46 +02:00
parent 35a000222c
commit f5468f0d36
9 changed files with 327 additions and 41 deletions
+2 -30
View File
@@ -19,21 +19,10 @@ func ValidateCanonicalPath(path string) error {
return nil
}
// ReadCanonicalRegular opens a canonical regular file after rejecting symlinked parents, then
// bounds reads against the opened handle rather than a pre-open size check.
func ReadCanonicalRegular(path string, maximum int64) ([]byte, error) {
if err := ValidateCanonicalPath(path); err != nil {
return nil, err
}
if err := rejectSymlinkComponents(path); err != nil {
return nil, err
}
file, err := os.Open(path)
if err != nil {
func readBoundedRegularFile(file *os.File, maximum int64) ([]byte, error) {
if maximum < 0 || maximum == int64(^uint64(0)>>1) {
return nil, ErrUnsafeFile
}
defer file.Close()
info, err := file.Stat()
if err != nil || !info.Mode().IsRegular() {
return nil, ErrUnsafeFile
@@ -44,20 +33,3 @@ func ReadCanonicalRegular(path string, maximum int64) ([]byte, error) {
}
return contents, nil
}
func rejectSymlinkComponents(path string) error {
volume := filepath.VolumeName(path)
current := volume + string(filepath.Separator)
relative := strings.TrimPrefix(path, current)
for _, component := range strings.Split(relative, string(filepath.Separator)) {
if component == "" {
continue
}
current = filepath.Join(current, component)
info, err := os.Lstat(current)
if err != nil || info.Mode()&os.ModeSymlink != 0 {
return ErrUnsafeFile
}
}
return nil
}