CWE-377: Insecure Temporary File
Overview
A temporary file is insecure when its name is predictable, when its permissions leave it readable or writable by other local users, or when it sits unprotected in a shared directory. Any of those lets another account on the same machine read the contents, tamper with them, or plant a symlink at the path before the application opens it.
Relationship to Other CWEs
A finding maps here cleanly when the problem is the temporary file as a whole: a guessable path, a create that is not exclusive, a file left behind. It belongs one level down when the problem is specifically the permission bits, on the file or on the directory holding it.
The pages around it differ by which part of the exposure is at fault:
- CWE-377 (this page) - the temporary file itself is insecure: a predictable name, a non-atomic create, a shared directory, or a file that outlives the run
- CWE-732 (Incorrect Permission Assignment for Critical Resource) - the mode or ACL on a named resource grants more than it needs, whatever that resource is. It is the page for the permission bits themselves, including the sticky bit a shared directory such as
/tmpneeds; this page is what those bits mean for a file you create there - CWE-312 (Cleartext Storage of Sensitive Information) - what the file holds rather than how it was created. Credentials or PII spooled through
/tmpearn both, and the fixes are independent: encrypt or stop storing under CWE-312, and fix the name, mode and lifetime here
MITRE gives CWE-377 two Base children, neither with a page here: CWE-378 (Creation of Temporary File With Insecure Permissions) narrows this page to the file's own mode, and CWE-379 (Creation of Temporary File in Directory with Insecure Permissions) to the directory it lands in. A finding reported against either is covered below - the permissions section for CWE-378, the temp-directory section for CWE-379.
OWASP Classification
A01:2025 - Broken Access Control
Risk
High: A local attacker can read sensitive data such as PII or credentials out of /tmp, replace a temp file with a link to a file like /etc/passwd, tamper with the data the application reads back, or fill /tmp to cause a denial of service.
Remediation Steps
Core Principle: Create temporary files securely (random names, exclusive create, correct permissions) and avoid predictable paths.
Locate the insecure temporary file creation
- Start from the finding: the file, the line, and the call that creates the temp file
- Work out which part is insecure - a fixed or predictable filename, permissions such as 0666, or a shared directory such as /tmp
- Note what the file holds: credentials, PII, session data, encryption keys
- Trace its lifecycle from creation through use to deletion, or to the point where deletion is missing
Use secure temp file APIs (Primary Defense)
- Python:
import tempfile; with tempfile.NamedTemporaryFile(delete=True) as f: f.write(data)- auto-deletes on close - Java:
File temp = File.createTempFile("prefix", ".tmp"); temp.deleteOnExit();- unpredictable name, auto-cleanup - C:
int fd = mkstemp(template);- creates file atomically with unique name and mode 0600 - Node.js: Use built-in
fs.mkdtemp()for a private temp directory, or thetmp/tempnpm packages for auto-cleanup
Set restrictive permissions
- Create the file at mode 0600, owner read and write only:
os.open(path, os.O_CREAT|os.O_EXCL, 0o600)in Python - Mode 0644 or 0666 leaves the contents readable by any user on the machine
- Apply the mode at creation, not afterwards, by passing it to the call that creates the file. A chmod after the fact leaves a window in which the file exists at the umask default, and on some platforms the temp API already applies 0600 for you
- Set umask(077) so a file created without an explicit mode is not world-readable
Use unpredictable filenames, and don't rely on the name alone
- Let the platform's temp API pick the name:
mkstemp(),tempfile.mkstemp(),os.CreateTemp,Files.createTempFile(). Each generates the name and claims the file in one operation, which is the part that closes the race - Don't assume the name is cryptographically random. OpenJDK's is (
SecureRandom, in bothFile.createTempFile()andFiles.createTempFile(), though the javadoc does not promise it), but Go's comes from the runtime's general-purpose generator, Python's fromrandom.Random, and Cmkstemp()names vary by libc. Treat a temp filename as hard to guess, never as a secret - Don't build the name from a PID, a timestamp, or a sequence number. Those are easy to guess and enable race conditions
- Create with O_EXCL, which fails if the file already exists, so an attacker cannot pre-create the path or plant a symlink there. An unpredictable name without exclusive creation is not a fix
Use user-specific temp directories
- Prefer a fresh, randomly named directory per run:
mkdtemp(),os.MkdirTemp,tempfile.TemporaryDirectory(), andFiles.createTempDirectory()create it with mode 0700 in a single step - A fixed name under a shared temp root is not a private directory. Any local user can create
/tmp/myapp-$USERbefore you do, either as a directory they own or as a symlink pointing elsewhere.mkdir -p-style calls succeed against an existing directory, and achmodafterwards does not take ownership away from whoever created it - If the application needs a stable path, put it where only that user can write: the user's home directory,
$XDG_RUNTIME_DIR, or a service-owned directory such as/var/lib/myapp. If it has to live under the shared temp root, create it with a plainmkdirthat fails when the path already exists, then confirm with anlstatthat it is a directory rather than a symlink, owned by the expected user, and mode 0700 - Respect $TMPDIR - it is the user's or administrator's choice of temp location - but check first that the directory it names is owned by the right account and not world-writable
- Keep sensitive data out of shared /tmp, where other users can read and write
- Delete temp files and directories when the application exits, for example from an
atexithook
Test the temp file security fix
- Run the code twice and compare the names it creates: expect random names, not sequential ones
- Check the permissions with ls -la: expect 0600, not 0644 or 0666
- After the application exits, look in /tmp and confirm nothing it created is still there
- Exercise a path that writes credentials or PII, and confirm those files carry the same restrictive permissions
- Re-scan to confirm the finding is resolved
Common Vulnerable Patterns
- /tmp/app_PID.tmp (predictable)
- open("/tmp/data.txt", "w") (fixed name)
- Creating temp files mode 0666
- Not deleting temp files
- Storing credentials in /tmp
Common Pitfalls
- "Secure-looking" API that only reserves a name, not a file: A helper that generates an unpredictable filename and hands it back, without atomically creating the file at that path, leaves a window between the name being returned and the caller opening it. An attacker watching the temp directory can create a file or symlink there first, which defeats the point of the unpredictable name.
- Fixing the filename but not the permissions: Unpredictable, per-invocation names, but the file is still created with whatever the process umask allows. If that resolves to world-readable, any local user can still read the contents even though they can no longer guess the name.
- Securing creation but not cleanup: A random name, exclusive create, and tight permissions, but the file is only deleted on the normal success path. A crash, exception, or early return leaves it behind in a shared, discoverable location.
- Trusting an app- or user-controlled temp directory: A secure creation API pointed at a custom or environment-supplied directory, such as a
TMPDIRvalue taken from configuration or user input, without checking that directory's ownership and permissions. The creation itself is secure, but the directory it lands in may be shared or attacker-writable.
Language-Specific Guidance
Concrete APIs and framework detail for each stack:
- C# - Path.GetRandomFileName with FileMode.CreateNew, Directory.CreateTempSubdirectory, ACLs and UnixCreateMode
- Go - os.CreateTemp, os.MkdirTemp with secure permissions
- Java - Files.createTempFile, File.createTempFile, POSIX permissions
- JavaScript/Node.js - fs.mkdtemp, tmp package, secure file creation
- Python - tempfile module, mkstemp, NamedTemporaryFile, secure permissions