T09 · Insecure Skill Coding Practices
- Location
SKILL.md:42- Finding
Predictable Temporary Files Permit Symlink-Based File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 42–65
Vulnerability Type: Predictable temporary files and unsafe file creation
Risk Level: MediumVulnerable Code
bash # Run tests N times and collect results RESULTS_FILE="/tmp/flaky-results.json" echo '[]' > "$RESULTS_FILE" for i in $(seq 1 5); do echo "=== Run $i/5 ===" # Capture per-test results (adjust for your framework) npm test -- --json 2>/dev/null | python3 -c " import json, sys try: data = json.load(sys.stdin) for suite in data.get('testResults', []): for test in suite.get('testResults', []): print(f'{test[\"status\"]}\t{test[\"fullName\"]}') except: pass " >> "/tmp/run-$i.txt" done # Find tests with inconsistent results across runs python3 -c " import os, collections results = collections.defaultdict(list) for i in range(1, 6): path = f'/tmp/run-{i}.txt'Technical Analysis
The Skill instructs the user or Agent to create and append to predictable filenames in the shared
/tmpdirectory. Shell redirections such as>and>>follow symbolic links. The commands neither create files exclusively nor verify file ownership, type, or permissions before writing.A local attacker who can write to
/tmpcan pre-create/tmp/flaky-results.jsonor any/tmp/run-N.txtpath as a symbolic link to another file writable by the victim. When the Skill runs,echo '[]' > "$RESULTS_FILE"truncates the symlink target, while the test-result command appends output through/tmp/run-N.txt.The
RESULTS_FILEvariable is initialized but not used afterward, making that particular shared temporary-file write unnecessary for the declared workflow. The test result files are necessary for analysis, but they do not need globally predictable paths.Attack Path
- The attacker has local access to the same system and permission to create entries in the shared
/tmpdirectory. ...[truncated 1537 chars]
- The attacker has local access to the same system and permission to create entries in the shared
- Remediation
View remediation
Remediation Suggestions
Create a private, randomly named temporary directory and store all result files within it:
bash RESULTS_DIR="$(mktemp -d)" || exit 1 chmod 700 "$RESULTS_DIR" trap 'rm -rf -- "$RESULTS_DIR"' EXIT for i in $(seq 1 5); do RUN_FILE="$RESULTS_DIR/run-$i.txt" npm test -- --json 2>/dev/null | python3 -c ' import json, sys try: data = json.load(sys.stdin) for suite in data.get("testResults", []): for test in suite.get("testResults", []): print(f"{test[\"status\"]}\t{test[\"fullName\"]}") except Exception: pass ' >> "$RUN_FILE" doneUpdate the analysis code to read from
RESULTS_DIR, preferably by passing the directory as a command-line argument or environment variable rather than embedding a fixed path.Additional hardening measures:
- Remove the unused
/tmp/flaky-results.jsoninitialization. - Set a restrictive umask, such as
umask 077, before creating temporary artifacts. - Do not use fixed filenames directly under shared temporary directories.
- Ensure cleanup is registered immediately after successful temporary-directory creation.
- Avoid executing the workflow with elevated privileges.
- If individual files must be created outside a private directory, use exclusive creation and reject symbolic links rather than relying on ordinary shell redirection.
- Remove the unused
