From b391e649d2aeed3922465a361cc8ee910d6605e7 Mon Sep 17 00:00:00 2001 From: admin-mf Date: Thu, 5 Mar 2026 23:59:12 -0600 Subject: [PATCH] security(tools): use crypto/rand for temp file naming Replace predictable PID+nanosecond temp file names with cryptographically random hex strings to prevent symlink pre-placement attacks. Co-Authored-By: Claude Opus 4.6 --- pkg/tools/filesystem.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/tools/filesystem.go b/pkg/tools/filesystem.go index d857eb090..e1a470d6e 100644 --- a/pkg/tools/filesystem.go +++ b/pkg/tools/filesystem.go @@ -2,13 +2,14 @@ package tools import ( "context" + "crypto/rand" + "encoding/hex" "fmt" "io/fs" "os" "path/filepath" "regexp" "strings" - "time" "github.com/sipeed/picoclaw/pkg/fileutil" ) @@ -340,7 +341,11 @@ func (r *sandboxFs) WriteFile(path string, data []byte) error { // Use atomic write pattern with explicit sync for flash storage reliability. // Using 0o600 (owner read/write only) for secure default permissions. - tmpRelPath := fmt.Sprintf(".tmp-%d-%d", os.Getpid(), time.Now().UnixNano()) + randBytes := make([]byte, 8) + if _, err := rand.Read(randBytes); err != nil { + return fmt.Errorf("failed to generate random bytes for temp file: %w", err) + } + tmpRelPath := fmt.Sprintf(".tmp-%s", hex.EncodeToString(randBytes)) tmpFile, err := root.OpenFile(tmpRelPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600) if err != nil {