T09 · Insecure Skill Coding Practices
- Location
scripts/openclaw_security_audit.py:345- Finding
Predictable Report Path Permits Information Disclosure and Symbolic-Link File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/openclaw_security_audit.py:17-19, 345-356
Vulnerability Type: Unsafe temporary-file handling
Risk Level: MediumVulnerable Code
python REPORT_DIR = Path('/tmp/openclaw-security-reports') DATE_STR = datetime.date.today().isoformat() REPORT_FILE = REPORT_DIR / f'report-{DATE_STR}.txt'python def setup_report_dir() -> None: REPORT_DIR.mkdir(parents=True, exist_ok=True) def write_report(content: str) -> None: with open(REPORT_FILE, 'w', encoding='utf-8') as f: f.write(content) def append_report(content: str) -> None: with open(REPORT_FILE, 'a', encoding='utf-8') as f: f.write(content)Technical Analysis
The script stores security reports under a globally predictable directory and filename in
/tmp. It creates the directory with default permissions andexist_ok=True, without confirming that the directory is owned by the current user, is not a symbolic link, or has restrictive permissions.The subsequent calls to
open()follow symbolic links and do not use secure creation controls such asO_EXCLorO_NOFOLLOW. The report file's effective permissions also depend on the process umask; with a common umask of022, it may be created as world-readable.Reports can contain sensitive operational information, including listening ports, process details, cron entries, login records, file-change information, configuration permissions, and installed Skill sources. The risk increases substantially if the audit is run as root or another privileged account.
Attack Path
- A local attacker predicts the report directory and daily filename:
/tmp/openclaw-security-reports/report-YYYY-MM-DD.txt. - Before the victim runs the audit, the attacker creates the report directory with permissions that allow the victim to write into it.
- The attacker places a symbolic link at the expected report f ...[truncated 1153 chars]
- A local attacker predicts the report directory and daily filename:
- Remediation
View remediation
Remediation Suggestions
- Store reports in a user-private state directory rather than a shared predictable
/tmplocation. - If temporary storage is required, use
tempfile.mkdtemp()ortempfile.NamedTemporaryFile()with a securely randomized name. - Create the report directory with mode
0700and verify its owner before every use. - Create report files with mode
0600. - Use low-level secure creation flags such as
O_CREAT | O_EXCL | O_NOFOLLOW, followed byos.fdopen(). - Reject existing files, symbolic links, and directories not owned by the effective user.
- Write reports atomically to a securely created temporary file and rename them after successful completion.
- Warn users against running the audit as root unless a specific check requires elevated access.
- Store reports in a user-private state directory rather than a shared predictable
