fix(auth): harden tht auth mutations

This commit is contained in:
2026-08-16 19:37:12 +02:00
parent 9646ae09a0
commit 856ac05edc
6 changed files with 245 additions and 31 deletions
+26
View File
@@ -43,6 +43,24 @@ func replaceCanonicalRegular(path string, contents []byte) error {
return nil
}
func removeCanonicalPrivateRegular(path string) error {
directory, target, err := openCanonicalParentDirectory(path)
if err != nil {
return ErrUnsafeFile
}
defer unix.Close(directory)
if err := requirePrivateRegularAt(directory, target); err != nil {
return ErrUnsafeFile
}
if err := unix.Unlinkat(directory, target, 0); err != nil {
return ErrUnsafeFile
}
if err := unix.Fsync(directory); err != nil {
return ErrUnsafeFile
}
return nil
}
func openCanonicalParentDirectory(path string) (int, string, error) {
components := strings.Split(strings.TrimPrefix(path, string(os.PathSeparator)), string(os.PathSeparator))
if len(components) < 2 || components[0] == "" || components[len(components)-1] == "" {
@@ -72,6 +90,14 @@ func requireSingleRegularAt(directory int, name string) error {
return nil
}
func requirePrivateRegularAt(directory int, name string) error {
var stat unix.Stat_t
if err := unix.Fstatat(directory, name, &stat, unix.AT_SYMLINK_NOFOLLOW); err != nil || stat.Mode&unix.S_IFMT != unix.S_IFREG || stat.Nlink != 1 || stat.Mode&0o7777 != 0o600 {
return ErrUnsafeFile
}
return nil
}
func writePrivateTemporaryAt(directory int, contents []byte) (string, error) {
for attempt := 0; attempt < 16; attempt++ {
name, err := randomTemporaryName()