Files
beads/cmd/bd/setup/utils.go
Steve Yegge b6870de7f8 Fix: Change file permissions from 0644 to 0600 for security
The gosec linter (G302) requires file permissions to be 0600 or less
for security. Updated atomicWriteFile to use 0600 (owner read/write only)
instead of 0644 (world readable).

This affects config files written by bd setup commands (cursor, aider,
claude), making them only accessible by the owner.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 20:11:52 -08:00

71 lines
1.8 KiB
Go

package setup
import (
"fmt"
"os"
"path/filepath"
)
// atomicWriteFile writes data to a file atomically using a unique temporary file.
// This prevents race conditions when multiple processes write to the same file.
func atomicWriteFile(path string, data []byte) error {
dir := filepath.Dir(path)
// Create unique temp file in same directory
tmpFile, err := os.CreateTemp(dir, ".*.tmp")
if err != nil {
return fmt.Errorf("create temp file: %w", err)
}
tmpPath := tmpFile.Name()
// Write data
if _, err := tmpFile.Write(data); err != nil {
_ = tmpFile.Close() // best effort cleanup
_ = os.Remove(tmpPath) // best effort cleanup
return fmt.Errorf("write temp file: %w", err)
}
// Close temp file
if err := tmpFile.Close(); err != nil {
_ = os.Remove(tmpPath) // Best effort cleanup
return fmt.Errorf("close temp file: %w", err)
}
// Set permissions to 0600 (owner read/write only)
if err := os.Chmod(tmpPath, 0600); err != nil {
_ = os.Remove(tmpPath) // Best effort cleanup
return fmt.Errorf("set permissions: %w", err)
}
// Atomic rename
if err := os.Rename(tmpPath, path); err != nil {
_ = os.Remove(tmpPath) // Best effort cleanup
return fmt.Errorf("rename temp file: %w", err)
}
return nil
}
// DirExists checks if a directory exists
func DirExists(path string) bool {
info, err := os.Stat(path)
return err == nil && info.IsDir()
}
// FileExists checks if a file exists
func FileExists(path string) bool {
info, err := os.Stat(path)
return err == nil && !info.IsDir()
}
// EnsureDir creates a directory if it doesn't exist
func EnsureDir(path string, perm os.FileMode) error {
if DirExists(path) {
return nil
}
if err := os.MkdirAll(path, perm); err != nil {
return fmt.Errorf("create directory: %w", err)
}
return nil
}