Predictable temp directory paths in pack management enable symlink attacks (CWE-377)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 6.5k
- Forks
- 787
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Pack management functions use hardcoded, predictable paths under /tmp/ with os.mkdir instead of tempfile.mkdtemp. This creates a TOCTOU (time-of-check-time-of-use) race condition where a local attacker can pre-create a symlink at the expected path, causing StackStorm to write pack files to an arbitrary location.
Affected Files
st2common/st2common/services/packs.py
Three functions use predictable temp paths:
# Line 426
def temp_backup_action_files(pack_base_path, metadata_file, entry_point, temp_sub_dir):
temp_dir_path = "/tmp/%s" % temp_sub_dir
os.mkdir(temp_dir_path)
# Line 450
def restore_temp_action_files(pack_base_path, metadata_file, entry_point, temp_sub_dir):
temp_dir_path = "/tmp/%s" % temp_sub_dir
# Line 468
def remove_temp_action_files(temp_sub_dir):
temp_dir_path = "/tmp/%s" % temp_sub_dir
if os.path.isdir(temp_dir_path):
shutil.rmtree(temp_dir_path)
st2common/st2common/util/pack_management.py
# Line 120-123
temp_dir_name = hashlib.md5(
pack_url.encode(), **hashlib_kwargs
).hexdigest()
lock_file = LockFile("/tmp/%s" % (temp_dir_name))
The lock file path is derived from an MD5 hash of the pack URL, which is predictable and not collision-resistant.
Impact
A local attacker with write access to /tmp/ can:
-
Symlink attack on
temp_backup_action_files: Pre-create a symlink at the expected path beforeos.mkdiris called. If the symlink points to a directory the attacker controls, pack files will be written there, potentially leaking sensitive configuration or entry point code. -
Symlink attack on
restore_temp_action_files: Replace the temp directory with a symlink pointing to attacker-controlled content. When StackStorm restores from the "backup," it copies the attacker's files into the pack directory, achieving arbitrary code execution via a malicious entry point. -
Lock file manipulation: The predictable lock file path allows an attacker to pre-create the lock file, causing a denial of service (pack installations hang waiting for the lock), or to delete the lock file to cause concurrent pack installations to race.
Recommended Fix
Use tempfile.mkdtemp for all temporary directories:
import tempfile
# Instead of:
temp_dir_path = "/tmp/%s" % temp_sub_dir
os.mkdir(temp_dir_path)
# Use:
temp_dir_path = tempfile.mkdtemp(prefix="st2_pack_backup_")
For the lock file, use a directory under StackStorm's control (e.g., /opt/stackstorm/locks/) rather than /tmp/.
References
- CWE-377: Insecure Temporary File
- CWE-362: Race Condition (TOCTOU)
- Discovered via manual code review
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in st2common/st2common/services/packs.py by reading temp_backup_action_files, restore_temp_action_files, and remove_temp_action_files, then inspect lock creation in st2common/st2common/util/pack_management.py. Replace predictable temporary paths and the /tmp-based lock path with secure handling, while preserving pack backup, restore, removal, and installation locking behavior. Done means these operations no longer expose predictable /tmp paths to symlink or lock-file attacks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100