fix(auth): harden Windows auth store privacy

This commit is contained in:
2026-08-16 18:44:38 +02:00
parent f6e4dbcae2
commit 25ee8b87d1
8 changed files with 556 additions and 31 deletions
+18 -10
View File
@@ -14,38 +14,41 @@ import (
const windowsReplaceMoveFlags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH
func replaceCanonicalRegular(path string, contents []byte) error {
directory := filepath.Dir(path)
if err := requireCanonicalDirectory(directory); err != nil || !safeExistingRegular(path) {
parents, target, err := openCanonicalWindowsParent(path)
if err != nil {
return ErrUnsafeFile
}
temporary, err := writePrivateTemporary(directory, contents)
defer parents.Close()
if len(parents.handles) == 0 || validateOwnerOnlyDACL(parents.handles[len(parents.handles)-1]) != nil || !safeExistingRegular(filepath.Join(parents.directory, target)) {
return ErrUnsafeFile
}
temporary, err := writePrivateTemporary(parents.directory, contents)
if err != nil {
return ErrUnsafeFile
}
defer func() { _ = os.Remove(temporary) }()
if !safeExistingRegular(path) {
if !safeExistingRegular(filepath.Join(parents.directory, target)) {
return ErrUnsafeFile
}
from, err := windows.UTF16PtrFromString(temporary)
if err != nil {
return ErrUnsafeFile
}
to, err := windows.UTF16PtrFromString(path)
to, err := windows.UTF16PtrFromString(filepath.Join(parents.directory, target))
if err != nil {
return ErrUnsafeFile
}
if err := windows.MoveFileEx(from, to, windowsReplaceMoveFlags); err != nil {
return ErrUnsafeFile
}
if err := ValidatePrivateRegular(filepath.Join(parents.directory, target)); err != nil {
return ErrUnsafeFile
}
return nil
}
func safeExistingRegular(path string) bool {
handle, err := openWindowsComponent(path, false)
if err != nil {
return false
}
return windows.CloseHandle(handle) == nil
return ValidatePrivateRegular(path) == nil
}
func writePrivateTemporary(directory string, contents []byte) (string, error) {
@@ -62,6 +65,11 @@ func writePrivateTemporary(directory string, contents []byte) (string, error) {
if err != nil {
return "", err
}
if err := ProtectPrivateRegular(path); err != nil {
_ = file.Close()
_ = os.Remove(path)
return "", err
}
if err := file.Chmod(0o600); err == nil {
var written int
written, err = file.Write(contents)