Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Creation of a directory from within a Python program can pose security issues if not handled carefully.

Directory creation is possible with several Python constructs:

Direct file system calls require careful input validation to prevent vulnerabilities.

Security concerns

Creating a directory using Python code is in essence not a security issue. BUT...

Minimal needed is validation of input if a directory is created upon user input or based on other input.

The following security risks are present:

1. Directory Traversal/Path Manipulation

2. Permission Issues

Too often Python programs have too many privileges when executed!

3. Race Conditions

A simple mitigation is:

Preventive measures

Some simple mitigations that should be present are:

  1. Use os.makedirs(path, mode, exist_ok=True) or pathlib.Path(path).mkdir(parents=True, exist_ok=True): These are the preferred and safest ways to create directories, handling recursive creation and avoiding errors if the directory already exists.

  2. Set appropriate permissions (mode) for the application.

  3. Use tempfile.mkdtemp() for secure temporary directory creation within Python.

  4. Monitor storage used by the program and set boundaries.

  5. Use the Principle of Least Privilege: Run your Python program with the minimum necessary permissions on the operating system!

  6. Implement error handling: Use try-except blocks to gracefully handle potential OSError exceptions (e.g., PermissionError, FileExistsError, FileNotFoundError).

Example

Insecure Directory Creation

The following code contains multiple security weaknesses:

import os

# INSECURE: Directly using user input to create a directory
user_input = input("Enter directory name to create: ")

# No input validation, no path sanitisation
os.mkdir(user_input)

# INSECURE: Overly permissive directory (world-writable)
os.makedirs("/tmp/app_cache", mode=0o777)

# INSECURE: Race condition pattern (check-then-act)
if not os.path.exists("/tmp/myapp/data"):
    os.makedirs("/tmp/myapp/data")

What is wrong with this code?

WeaknessExplanation
No input validationUser could enter ../../../etc/critical to create directories outside the intended scope
No path sanitisationSpecial characters or path traversal sequences are not filtered
Overly permissive mode (0o777)Any user on the system can read, write, or execute files in this directory
Race conditionBetween os.path.exists() and os.makedirs(), another process could create the directory or a malicious file

Example attack: If an attacker supplies ../../../../home/user/.ssh as input, they might create a directory that interferes with SSH key storage, leading to credential theft or unauthorised access.

Quick Reference: Insecure vs Secure Patterns in Python

Insecure PatternSecure Replacement
os.mkdir(user_input)Validate input, use Path(base) / sanitised, then mkdir()
os.makedirs(path, mode=0o777)path.mkdir(mode=0o700) or 0o750
if not os.path.exists(path): os.makedirs(path)path.mkdir(exist_ok=True) (atomic)
Creating directories in /tmp directlytempfile.mkdtemp() for temporary directories
Hardcoded paths without validationResolve paths and verify they remain within a base directory

More information