VNX-378: Creation of Temporary File With Insecure Permissions
C/C++ temporary files created so other local users can read, write or claim them: tmpnam/tempnam/mktemp, open()/creat() in /tmp with a mode other users can use, fopen() writing a fixed name in /tmp, and chmod() widening a mkstemp() file.
| Field | Value |
|---|---|
| Rule ID | VNX-378 |
| Severity | High |
| SARIF level | error |
| Kind | sast |
| Languages | C, C++ |
| CWE | CWE-378 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:H/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:H/DI:H/EX:H/EC:N/P:H |
| Tags | tempfile-insecure cwe-378 |
| Source | internal/sast/rules/vnx-378.rego |
Overview
VNX-378 maps to CWE-378: Creation of Temporary File With Insecure Permissions. It reports:
- the name-only temporary file functions
tmpnam,tmpnam_r,tempnam,mktempand Windows_mktemp/_tempnam/_wtmpnam/_wmktemp(alsostd::or::qualified), which return a name without creating the file; open()orcreat()of a path in/tmp/,/var/tmp/or/dev/shm/(a literal, or a variable assigned one in the 10 lines above) with a mode that grants other users access (an octal mode whose last digit is not 0,S_IRWXO,S_IROTH,S_IWOTH,S_IXOTH) and noO_EXCL;fopen()for writing or appending (not the exclusivexmode) of a fixed name in those directories, the path a literal or a variable assigned one or filled bysnprintf/sprintf/strcpyin the 10 lines above;fchmod()/chmod()that opens such a mode on a descriptor or template returned bymkstemp()in the 10 lines above.
Not reported: mkstemp, mkostemp, mkdtemp, tmpfile, owner-only modes (0600, 0640, S_IRUSR | S_IWUSR), opens outside shared temporary directories, prototypes and C++ members declared with these names, lookalike identifiers and members (my_mktemp, obj.mktemp()), read-only opens, comments and string literals.
Why This Matters
A temporary file whose name is chosen before it is created can be created first by another local user, often as a symlink to a file the program can write. A file in a shared directory created readable or writable by others leaks or accepts whatever the program puts in it.
What Gets Flagged
if (tmpnam(name) == NULL) // FLAGGED
char *p = mktemp(tmpl); // FLAGGED
int fd = open("/tmp/agent.lock", O_RDWR | O_CREAT, 0666); // FLAGGED
return creat("/tmp/daemon.pid", 0644); // FLAGGED
FILE *fp = fopen("/tmp/state.dump", "w"); // FLAGGED
int fd = mkstemp(tmpl);
fchmod(fd, 0666); // FLAGGED
Not flagged: int fd = mkstemp(tmpl);, FILE *f = tmpfile();, open("/tmp/x", O_CREAT | O_EXCL | O_WRONLY, 0600).
Remediation
- Use
mkstemp()/mkostemp()(files) ormkdtemp()(directories), which create the entry atomically with mode 0600/0700, ortmpfile(). - When a fixed path is unavoidable, open it with
O_CREAT | O_EXCLand mode0600, in a directory only the program’s user can write. - Do not widen the permissions of a temporary file after creating it.
References
- CWE-378: Creation of Temporary File With Insecure Permissions
- SEI CERT FIO21-C: Do not create temporary files in shared directories
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-378
// nosec vnx-378
Or record an ignore rule: vulnetix ignore add --rule vnx-378 --reason "...". See Suppressing findings.