T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/main.py:17
- Finding
- Terminal Session Recordings Are Stored Without Enforced Private Permissions## Vulnerability Details **File Location**: `scripts/main.py:17-20` and `scripts/main.py:138-139` **Vulnerability Type**: Insecure permissions for potentially sensitive terminal recordings and metadata **Risk Level**: Medium ### Vulnerable Code ```python class TerminalSessionManager: def __init__(self, sessions_dir: Optional[str] = None): if sessions_dir: self.sessions_dir = Path(sessions_dir) else: self.sessions_dir = Path.home() / ".terminal-sessions" self.sessions_dir.mkdir(parents=True, exist_ok=True) ``` ```python with open(paths['meta'], 'w') as f: json.dump(meta, f, indent=2) ``` ### Technical Analysis The session directory and metadata files are created without explicitly enforcing owner-only permissions. `Path.mkdir()` and `open()` therefore rely on the process umask. The `.typescript` and `.timing` files are created by the inherited `script` subprocess under the same environment-dependent permission policy. Terminal recordings can contain sensitive commands, credentials typed or displayed during a session, API tokens, filesystem paths, source code, and confidential command output. On a multi-user system with a permissive umask, or where `~/.terminal-sessions` already has unsafe permissions, another local account may be able to enumerate or read these files. The application also does not verify that an existing session directory is owned by the current user or that its permissions prohibit access by other users. Consequently, confidentiality depends on external host configuration rather than a security property enforced by the skill. ### Attack Path 1. A victim runs the recording command and captures a terminal session containing sensitive commands or output. 2. The process uses a permissive umask, or the pre-existing `~/.terminal-sessions` directory has group- or world-accessible permissions. 3. The tool creates metadata and invokes `script` without first enforcing restrictive director ...[truncated 1067 chars]
- Remediation
- ## Remediation Suggestions 1. Create the session directory with owner-only permissions and correct unsafe permissions on an existing directory: ```python self.sessions_dir.mkdir(parents=True, mode=0o700, exist_ok=True) self.sessions_dir.chmod(0o700) ``` 2. Verify that an existing session directory is owned by the current user before using it. Refuse operation when ownership is unexpected rather than silently trusting the path. 3. Create metadata files atomically with mode `0600`, for example by using `os.open()` with `O_CREAT | O_EXCL | O_WRONLY` and an explicit permission mode: ```python fd = os.open(paths['meta'], os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600) with os.fdopen(fd, 'w') as f: json.dump(meta, f, indent=2) ``` 4. Ensure that the `script` subprocess creates `.typescript` and `.timing` files under a restrictive `077` umask. Where possible, pre-create output files securely or use a narrowly scoped subprocess setup that applies the restrictive umask. 5. After recording, verify that all generated files are regular files owned by the current user and enforce mode `0600`. 6. Avoid following attacker-controlled symbolic links when creating or replacing session artifacts. Use exclusive and no-follow file creation primitives where the platform supports them. 7. Document that terminal recordings may contain secrets and advise users to review recordings before sharing or exporting them.
