T09 · Insecure Skill Coding Practices
- Location
scripts/_shopee_follow_prize_common.py:218- Finding
Unsanitized SESSION_ID Allows Filesystem Path Traversal
- Content
View full analysis
str: env = os.environ.get("SESSION_ID") if env: return env.strip() if "_auto" not in _LF_SESSION_CACHE: _LF_SESSION_CACHE["_auto"] = ( _lf_time.strftime("%H%M%S", _lf_time.localtime(ts)) + "-" + _lf_secrets.token_hex(3) ) return _LF_SESSION_CACHE["_auto"] ``` The value reaches filesystem operations at `scripts/_shopee_follow_prize_common.py:321-329`: ```python sid = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _lf_ensure_meta(root, session_dir, date_str, sid, ts) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join(data_dir, f"{slug}-{int(ts * 1_000_000)}.json") try: with open(out, "w", encoding="utf-8") as f: ``` The onboarding workflow contains the same issue at `scripts/onboarding.py:153-158`: ```python def session_dir() -> str: ts = time.time() sid = (os.environ.get("SESSION_ID") or "").strip() or ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3)) path = os.path.join(_linkfox_root(), time.strftime("%Y-%m-%d", time.localtime(ts)), sid) os.makedirs(path, exist_ok=True) return path ``` ### Technical Analysis `SESSION_ID` is read directly from the process environment and used as a path component without validation or canonical containment checks. If `SESSION_ID` is an absolute path, `os.path.join()` discards the preceding root and date components. If it contains traversal components such as `../`, path n ...[truncated 2101 chars]- Remediation
View remediation
str: value = value.strip() if not _SESSION_ID_PATTERN.fullmatch(value): raise ValueError("Invalid SESSION_ID") return value ``` Apply this validation in both `_lf_session_id()` and `session_dir()`. 2. **Enforce canonical path containment** Resolve the intended root and final path before creating directories: ```python root_path = Path(root).resolve() session_path = (root_path / date_str / sid).resolve() if session_path != root_path and root_path not in session_path.parents: raise ValueError("Session path escapes the configured output root") ``` Perform the same check for onboarding output paths. 3. **Reject path syntax explicitly** Reject session identifiers containing: - `/` or `\` - `.` or `..` path components - Absolute paths - Null bytes - Platform-specific drive or UNC prefixes Strict allowlisting is preferable to attempting to remove dangerous characters. 4. **Use restrictive filesystem permissions** Create directories and response files with permissions limited to the current user where supported. API responses and payment data should not be broadly readable. 5. **Harden against symbolic-link attacks** For predictable metadata files, avoid following symbolic links where supported. Use secure file-opening flags such as `O_NOFOLLOW`, verify the destination is a regular file, and write updates atomically through a securely created temporary file followed by a controlled replacement. 6. **Remove the undocumented temporary-directory fallback or document it accurately** The implementation can fall back to the system temporary directory even though `SKILL.md` states that writing to `/tmp` is prohibited. Prefer failing closed when approved out ...[truncated 32 chars]
