Summary
File.Write() writes new contents to a temp file in the same directory as the target, then atomically renames it over the target. The temp file's name comes from RandomString(20) in strings.go, which uses the global, non-cryptographic math/rand PRNG seeded once with time.Now().UnixNano().
// strings.go
b[i] = characters[rand.Intn(len(characters))]
// file_handling.go
tempName := filepath.Join(f.Dir(), RandomString(20))
if err := os.WriteFile(tempName, []byte(content), f.Mode()); err != nil { ... }
Impact (Security: High)
Anyone who can write to the same directory as a file find-replace is rewriting can predict (or just observe) the temp-file name and pre-create it as a symlink to a path the running user can write but the attacker cannot. os.WriteFile opens with O_WRONLY|O_CREATE|O_TRUNC — O_CREATE does not require the file to be new, so the open follows the attacker's symlink and writes the new content (or truncates it) at the attacker-chosen location.
This is the classic insecure-tempfile-in-shared-directory pattern. Predictable RNG only makes it easier; the underlying bug is using O_CREATE instead of O_CREATE|O_EXCL together with secure naming.
The risk is highest when find-replace is run by a privileged user (e.g., during deployment scripts, in a CI runner that shares /tmp-like state, or when the tool processes a directory writable by another user).
Suggested Fix
- Create the temp file with
os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_EXCL, mode) (or use os.CreateTemp, which does this internally with a CSPRNG name).
- Replace
math/rand with crypto/rand for any name that ends up in a path namespace.
- Always remove the temp file on error paths.
Files
file_handling.go:78-88 (Write)
strings.go:5-18 (RandomString)
Summary
File.Write()writes new contents to a temp file in the same directory as the target, then atomically renames it over the target. The temp file's name comes fromRandomString(20)instrings.go, which uses the global, non-cryptographicmath/randPRNG seeded once withtime.Now().UnixNano().Impact (Security: High)
Anyone who can write to the same directory as a file
find-replaceis rewriting can predict (or just observe) the temp-file name and pre-create it as a symlink to a path the running user can write but the attacker cannot.os.WriteFileopens withO_WRONLY|O_CREATE|O_TRUNC—O_CREATEdoes not require the file to be new, so the open follows the attacker's symlink and writes the new content (or truncates it) at the attacker-chosen location.This is the classic insecure-tempfile-in-shared-directory pattern. Predictable RNG only makes it easier; the underlying bug is using
O_CREATEinstead ofO_CREATE|O_EXCLtogether with secure naming.The risk is highest when
find-replaceis run by a privileged user (e.g., during deployment scripts, in a CI runner that shares/tmp-like state, or when the tool processes a directory writable by another user).Suggested Fix
os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_EXCL, mode)(or useos.CreateTemp, which does this internally with a CSPRNG name).math/randwithcrypto/randfor any name that ends up in a path namespace.Files
file_handling.go:78-88(Write)strings.go:5-18(RandomString)