T09 · Insecure Skill Coding Practices
- Location
scripts/codex_auth.py:518- Finding
Shell Command Injection Through Unsanitized Profile Identifiers
- Content
View full analysis
str: return (profile_id or "unknown").replace(":", "_") ``` ```python if args.queue_apply: os.makedirs("/tmp/openclaw", exist_ok=True) safe_profile = safe_profile_slug(profile_id) payload_path = f"/tmp/openclaw/codex-auth-apply-{safe_profile}.json" script_path = f"/tmp/openclaw/codex-auth-apply-{safe_profile}.sh" log_path = f"/tmp/openclaw/codex-auth-apply-{safe_profile}.log" status_path = per_profile_status_path(profile_id) write_json_atomic(payload_path, {"profile": profile_id, "tokens": tokens}) py = shlex.quote(sys.executable or "python3") this_file = shlex.quote(os.path.abspath(__file__)) payload_q = shlex.quote(payload_path) auth_q = shlex.quote(args.auth_path) log_q = shlex.quote(log_path) allow_default_flag = " --allow-default" if (profile_id == "openai-codex:default" and args.allow_default) else "" script = f"""#!/usr/bin/env bash set -euo pipefail {{ echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] codex-auth apply start profile={profile_id}"; {py} {this_file} apply --payload {payload_q} --auth-path {auth_q}{allow_default_flag}; echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] codex-auth apply done profile={profile_id}"; }} >> {log_q} 2>&1 """ Path(script_path).write_text(script, encoding="utf-8") os.chmod(script_path, 0o700) launcher = "nohup" unit_name = f"codex-auth-apply-{safe_profile}-{int(time.time())}" try: sd = subprocess.run( ["systemd-run", "--user", "--unit", unit_name, "--collect", "/bin/bash", script_path], capture_output=True, text=True, timeout=15, ) if sd.returncode == 0: launcher = "systemd-run" else: subprocess ...[truncated 2791 chars]- Remediation
View remediation
str: if not PROFILE_RE.fullmatch(value): raise ValueError("Invalid profile identifier") return value ``` 2. Explicitly reject path separators, whitespace, control characters, shell metacharacters, backticks, dollar signs, and newline characters. 3. Do not generate executable shell scripts containing dynamic data. Implement the queued apply operation in Python and invoke subprocesses with fixed argument arrays. 4. If shell generation cannot immediately be removed, shell-quote every dynamic value with `shlex.quote()` and avoid placing dynamic values inside executable shell syntax. 5. Derive filenames and systemd unit names from a cryptographic random identifier rather than directly from a profile name. 6. Apply the same validation to profile identifiers loaded from `auth-profiles.json`, since that file may contain externally modified or previously malicious values. 7. Add regression tests using values containing `$(...)`, backticks, semicolons, quotes, newlines, spaces, `../`, and absolute paths. ]]>
