T09 · Insecure Skill Coding Practices
- Location
scripts/_shopee_livestream_common.py:190- Finding
Unvalidated SESSION_ID permits response files to escape the intended storage directory
- Content
View full analysis
Vulnerability Details
File Location:
scripts/_shopee_livestream_common.py:190-219, 322-330
Vulnerability Type: Path traversal and unsafe temporary-file handling
Risk Level: MediumVulnerable Code
python def _lf_root() -> str: cached = _LF_SESSION_CACHE.get("_root") if cached: return cached candidates = [] acpx = (os.environ.get("ACPX_WORKSPACES") or "").strip() if acpx: acpx = acpx.split(os.pathsep)[0].strip() if acpx: candidates.append(os.path.join(acpx, "linkfox")) candidates.append(os.path.join(os.getcwd(), "linkfox")) candidates.append(os.path.join(os.path.expanduser("~"), "linkfox")) candidates.append(os.path.join(_lf_tempfile.gettempdir(), "linkfox")) for root in candidates: try: os.makedirs(root, exist_ok=True) probe = os.path.join(root, ".write_probe") with open(probe, "w", encoding="utf-8") as f: f.write("") os.remove(probe) except OSError: continue root = os.path.abspath(root) _LF_SESSION_CACHE["_root"] = root return root fallback = os.path.abspath(candidates[-1]) _LF_SESSION_CACHE["_root"] = fallback return fallbackpython def _lf_session_id(ts: float) -> 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"]python def emit_result(result, slug=SLUG, inline=False): serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = _lf_time.time() date_str = _lf_time.strftime("%Y-%m-%d", _lf_time.localtime(ts)) sid = _lf_session_id(ts) root = _l ...[truncated 3043 chars]- Remediation
View remediation
Remediation Suggestions
- Validate
SESSION_IDagainst a strict identifier allowlist, for example:python if not re.fullmatch(r"[A-Za-z0-9_-]{1,128}", sid): raise ValueError("Invalid SESSION_ID") - Reject absolute paths, path separators,
.components, and..components. - Resolve and enforce containment before creating directories:
python root_path = Path(root).resolve() session_path = (root_path / date_str / sid).resolve() session_path.relative_to(root_path) - Remove the shared temporary-directory fallback if
/tmpstorage is prohibited. Fail closed when approved storage locations are unavailable. - Create response directories and files with restrictive permissions, such as
0700for directories and0600for files. - Use no-follow and exclusive-creation semantics where practical to reduce symlink and race-condition exposure.
- Avoid persisting complete responses by default when they can contain sensitive data. Support field filtering, explicit opt-in, and retention controls.
- Validate
