mutated × shared — the answer changes between runs
Temp-File Check-Then-Use Race
A predictable temp path plus a gap between checking and opening it is a window another actor can slip a symlink through -- so the write lands elsewhere only when the timing lines up.
01the recipe
In the wild
compound ofFile & Network AccessCWE-367 TOCTOU (Time-of-Check to Time-of-Use)Time, Money & EntropyCWE-330 Weak RandomnesscompoundCWE-363 Link-Following RaceCWE-59 Link Following
example.py
# SMELL: predictable name + check-then-open lets a symlink slip in.
# (file/network access x time/money/entropy)
import os, time
path = f"/tmp/job-{int(time.time())}.tmp" # predictable, guessable name
if not os.path.exists(path): # time-of-check
with open(path, "w") as f: # time-of-use -- another process
f.write(secret) # may have planted a symlink here
# RIGHT: unpredictable name + atomic, no-follow create owns the check.
import tempfile
fd, path = tempfile.mkstemp() # O_EXCL|O_CREAT, random name
with os.fdopen(fd, "w") as f: # no check/use gap, no symlink
f.write(secret)The guessable name (from a clock) plus the existence-check-then-open gap is a window: between check and open another actor can drop a symlink, redirecting the write. It fires only when the interleaving lines up -- otherwise it looks fine.
// observed
race: the write follows a planted symlink (only sometimes) right: mkstemp creates atomically with O_EXCL -- no window, no follow
02weakness catalog
Mapped weaknesses (CWE)
On its own, this defect is catalogued by MITRE as one or more of these weaknesses. The exploitable vulnerability usually appears only when it chains or combines with another.