Skip to content

Commit b85330a

Browse files
committed
update + fixes
1 parent d86ee55 commit b85330a

3 files changed

Lines changed: 185 additions & 76 deletions

File tree

‎constructs/mktemp.md‎

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Mktemp Statement
2+
3+
The `tempfile.mktemp()` function in Python's standard library is **deprecated and insecure**. Its use introduces a critical **Time-of-Check to Time-of-Use (TOCTOU)** vulnerability that can be exploited by attackers to compromise your application.
4+
5+
:::{danger}
6+
**Never use `tempfile.mktemp()` in new code.** The function has been deprecated since Python 2.3 (2003) and removed from Python 3.12+ documentation as a recommended practice. Its continued use represents a significant security risk with no valid justification in modern applications.
7+
:::
8+
9+
## Security Concerns
10+
11+
### Time-of-Check to Time-of-Use (TOCTOU) Vulnerability
12+
13+
The fundamental flaw in `mktemp()` is the gap between generating a filename and actually using it:
14+
15+
```python
16+
# VULNERABLE PATTERN
17+
filename = tempfile.mktemp() # Step 1: Generate unique-sounding name
18+
# --- TIME GAP --- Attacker can create file here
19+
with open(filename, 'w') as f: # Step 2: Use the filename
20+
f.write(data)
21+
```
22+
23+
During this time gap, an attacker can:
24+
1. **Create the file** with malicious content before your application does
25+
2. **Create a symbolic link** pointing to a critical system file (e.g., `/etc/passwd`)
26+
3. **Replace the file** after your application creates it but before it's fully written
27+
4. **Create a directory** with the same name, causing your application to fail or behave unexpectedly
28+
29+
### Race Condition Exploitation
30+
31+
The TOCTOU vulnerability enables several attack vectors:
32+
33+
- **Symlink Attacks**: An attacker creates a symbolic link from the temporary filename to a sensitive file. When your application opens the file for writing, it overwrites the target instead.
34+
- **File Pre-creation**: An attacker creates the file before your application, potentially with malicious content or permissions that your application later reads.
35+
- **Denial of Service**: An attacker creates the file or directory, causing your application to crash or fail when attempting to create it.
36+
- **Data Leakage**: An attacker reads the file contents after creation but before your application secures them.
37+
38+
### No Atomicity Guarantees
39+
40+
`mktemp()` provides **no guarantees** about:
41+
- **Uniqueness**: The generated name is based on predictable patterns
42+
- **Exclusivity**: The file may not exist at creation time but could be created by an attacker
43+
- **Permissions**: Default permissions may be too permissive, exposing sensitive data
44+
- **Path Security**: The function does not verify the security of the parent directory
45+
46+
### Predictable Name Generation
47+
48+
The name generation algorithm in older Python versions was predictable, allowing attackers to:
49+
- Pre-emptively create files with known names
50+
- Calculate future filenames and exploit them
51+
- Create denial-of-service conditions by pre-creating many files
52+
53+
```python
54+
import tempfile
55+
56+
# These patterns might be predictable
57+
file1 = tempfile.mktemp() # /tmp/tmp123456
58+
file2 = tempfile.mktemp() # /tmp/tmp123457
59+
# Attacker could guess the pattern and pre-create files
60+
```
61+
62+
63+
## Preventive Measures
64+
65+
### Use `tempfile.mkstemp()` Instead
66+
67+
The safe alternative to `mktemp()` is `tempfile.mkstemp()`, which atomically creates a temporary file with exclusive access:
68+
69+
```python
70+
import tempfile
71+
import os
72+
73+
# SECURE: mkstemp() creates the file atomically
74+
fd, filename = tempfile.mkstemp(suffix='.txt', prefix='myapp_', dir='/secure/temp')
75+
76+
try:
77+
# Write data using the file descriptor
78+
with os.fdopen(fd, 'w') as f:
79+
f.write("Secure data")
80+
81+
# Use the filename if needed
82+
print(f"Created secure temp file: {filename}")
83+
finally:
84+
# Clean up
85+
os.unlink(filename)
86+
```
87+
88+
### Use Context Managers for Automatic Cleanup
89+
90+
For even better security and resource management, use `tempfile.TemporaryFile()` or `tempfile.NamedTemporaryFile()`:
91+
92+
```python
93+
import tempfile
94+
95+
# SECURE: Automatic cleanup and secure creation
96+
with tempfile.TemporaryFile(mode='w+', suffix='.txt', prefix='myapp_') as f:
97+
f.write("Sensitive data")
98+
f.seek(0)
99+
data = f.read()
100+
# File is automatically closed and deleted on context exit
101+
102+
# With a named file (visible in filesystem)
103+
with tempfile.NamedTemporaryFile(mode='w+', delete=True, suffix='.txt') as f:
104+
f.write("Another secure use case")
105+
# File remains accessible via f.name, but is deleted on close
106+
```
107+
108+
### Use `tempfile.TemporaryDirectory` for Secure Directories
109+
110+
For temporary directories, use the secure context manager:
111+
112+
```python
113+
import tempfile
114+
import os
115+
116+
# SECURE: Creates and automatically cleans up temporary directory
117+
with tempfile.TemporaryDirectory(prefix='myapp_') as temp_dir:
118+
temp_file = os.path.join(temp_dir, 'data.txt')
119+
with open(temp_file, 'w') as f:
120+
f.write("Secure temporary data")
121+
# Directory and all contents are removed on exit
122+
```
123+
124+
### Implement Defensive Practices
125+
126+
When creating temporary files, always:
127+
128+
1. **Set Appropriate Permissions**: Use `os.umask()` to set restrictive permissions
129+
2. **Verify Directory Security**: Ensure the target directory is not world-writable
130+
3. **Use Absolute Paths**: Avoid relying on relative paths or environment variables
131+
4. **Clean Up**: Always delete temporary files after use, even in error cases
132+
5. **Limit Exposure**: Minimize the time temporary files exist in the filesystem
133+
134+
### Use Secure Configuration
135+
136+
```python
137+
import tempfile
138+
import os
139+
import stat
140+
141+
def secure_temp_file(data, prefix='myapp_'):
142+
"""
143+
Create a secure temporary file with restrictive permissions.
144+
145+
Args:
146+
data: Content to write to the file
147+
prefix: Prefix for the temporary filename
148+
149+
Returns:
150+
The filename of the temporary file
151+
"""
152+
# Set restrictive umask temporarily
153+
old_umask = os.umask(0o177)
154+
155+
try:
156+
# Create secure temporary file
157+
fd, filename = tempfile.mkstemp(prefix=prefix, text=True)
158+
159+
# Set restrictive permissions (owner read/write only)
160+
os.fchmod(fd, stat.S_IRUSR | stat.S_IWUSR)
161+
162+
# Write data
163+
with os.fdopen(fd, 'w') as f:
164+
f.write(data)
165+
166+
return filename
167+
finally:
168+
# Restore original umask
169+
os.umask(old_umask)
170+
```
171+
172+
173+
## Discussion
174+
175+
**Historical Context**
176+
177+
`tempfile.mktemp()` was deprecated in Python 2.3 (2003) after security researchers identified widespread vulnerabilities in applications using the function. Despite being deprecated for over two decades, the function occasionally appears in legacy codebases and beginner tutorials, leading to continued security risks.
178+
179+
## More Information
180+
181+
- [Python `tempfile` Documentation](https://docs.python.org/3/library/tempfile.html)
182+
- [CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition](https://cwe.mitre.org/data/definitions/367.html)
183+
- [CWE-377: Insecure Temporary File](https://cwe.mitre.org/data/definitions/377.html)
184+
- [CWE-379: Creation of Temporary File in Directory with Incorrect Permissions](https://cwe.mitre.org/data/definitions/379.html)

‎constructs/tarfile.md‎

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -83,79 +83,3 @@ with tarfile.open("untrusted.tar.gz") as tar:
8383
- [Summary of Python tarfile Infinite Loop Vulnerability (CVE-2025-8194)](https://zeropath.com/blog/cve-2025-8194-python-tarfile-infinite-loop)
8484

8585

86-
87-
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
88-
The Python `tarfile` module makes it possible to read and write tar archives.
89-
90-
Code Audit checks on the use of:
91-
* `TarFile.extract` and
92-
* `TarFile.extractall`
93-
Using these methods in Python code can give serious security concerns.
94-
95-
96-
:::{admonition} The default rule is:
97-
:class: danger
98-
Assume all input is malicious.
99-
:::
100-
101-
Using these commands in Python code can expose systems to several risks:
102-
103-
* Privilege escalation: An attacker can change file permissions on sensitive files (for example, `/etc/shadow` or SSH keys) if the extraction process runs with root or elevated privileges.
104-
105-
* Sandbox escape: Many systems rely on extraction directories or temporary paths for isolation; malicious archives can break that isolation and allow code to operate outside the sandbox.
106-
107-
* Tampering and log evasion: By modifying file timestamps or other metadata, an attacker can obscure activity, confuse forensic timelines, or mislead incident response.
108-
109-
* Easy exploitation: Crafting a malicious tarball is straightforward and requires no specialized tools, making exploitation trivial for an attacker.
110-
111-
112-
:::{danger}
113-
Using `TarFile.extractall` or `TarFile.extract` is dangerous.
114-
Always. So good mitigation measurement **must** be present in the code!
115-
:::
116-
117-
But besides using these `tarfile` commands in your Python code, there have been some vulnerabilities with the `tarfile` module implementation in CPython in the past.
118-
119-
So from a security point of view checking if your code is extracting files using the `tarfile` command is vital.
120-
121-
:::{note}
122-
Use of the `tarfile` extraction methods in Python code should **always** be reviewed in depth!
123-
124-
This means:
125-
* Check if the code uses defence in-depth measures for extracting files.
126-
127-
* Check if the files that will be extracted by the Python code can be assumed secure, so not tampered with. If not: validate if enough additional mitigation measurements are in place when using this code.
128-
129-
Mitigation measurements are always context dependent, and can be e.g. running the Python program in an isolated environment.
130-
:::
131-
132-
## Preventive measures
133-
134-
Never extract archives from untrusted sources without prior inspection. It is possible that files are created outside of path, e.g. members that have absolute filenames starting with `"/"` or filenames with two dots `".."`.
135-
136-
Make sure a proper `filter` is set:
137-
```
138-
TarFile.extractall(path='.', members=None, *, numeric_owner=False, filter=None)
139-
```
140-
The filter argument specifies how members are modified or rejected before extraction. So set minimal `filter='data'` to prevent the most dangerous security issues, and read the Extraction filters section documentation for details.
141-
142-
143-
* Do not pass filter="tar" or filter="data" for untrusted archives.
144-
If you must unpack, force filter="none" and run in a dedicated, non-privileged container/VM.
145-
146-
:::{note}
147-
This validation test requires **always** human inspection if the construct is detected.
148-
No automatic test can give you enough confidence! So **no AI agent or other GenAI thing** will help you.
149-
150-
Using this construct is fine, but make sure you known how to prevent disasters!
151-
:::
152-
153-
## More info
154-
155-
* [CVE-2025-4330](https://www.cve.org/CVERecord?id=CVE-2025-4330)
156-
* [CVE-2024-12718](https://nvd.nist.gov/vuln/detail/CVE-2024-12718)
157-
* [CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')](https://cwe.mitre.org/data/definitions/22.html)
158-
* https://docs.python.org/3/library/tarfile.html#tarfile-extraction-filter
159-
* [What Is The Tarfile Vulnerability in Python?](https://www.securitycompass.com/kontra/what-is-the-tarfile-vulnerability-in-python/)
160-
* [Summary of Python tarfile Infinite Loop Vulnerability (CVE-2025-8194)](https://zeropath.com/blog/cve-2025-8194-python-tarfile-infinite-loop)
161-
* [Tarfile: Exploiting the World With a 15-Year-Old Vulnerability](https://www.trellix.com/blogs/research/tarfile-exploiting-the-world/)

‎toc.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ project:
4545
- file: constructs/weakhash.md
4646
- file: constructs/ftp.md
4747
- file: constructs/marshal.md
48+
- file: constructs/mktemp.md
4849

4950

5051
- file: guidelines/guidelines_intro.md

0 commit comments

Comments
 (0)