T09 · Insecure Skill Coding Practices
Warning
- Location
- check.sh:233
- Finding
- Full Process Command Lines Are Exposed and Persisted Without Redaction## Vulnerability Details **File Location**: `check.sh`, lines 233–258, 260, 384–400, and 404–430 **Vulnerability Type**: Sensitive information exposure through process enumeration and persistent state storage **Risk Level**: Medium ### Vulnerable Code ```python ps_out = run(["ps", "axo", "pid=,ppid=,pcpu=,rss=,etime=,comm=,args="]) processes = [] for line in ps_out.strip().split('\n'): parts = line.split(None, 6) if len(parts) < 7: continue pid, ppid, cpu, rss, elapsed, comm, args = parts pid = int(pid) ppid = int(ppid) cpu = float(cpu) rss_kb = int(rss) elapsed_secs = parse_elapsed(elapsed) command = args.strip() first_arg = command.split()[0] if command else "" name = os.path.basename(comm).strip() or os.path.basename(first_arg).strip() or comm.strip() or "unknown" # macOS sometimes truncates comm to 2 chars — fall back to first arg if len(name) <= 2 and first_arg: name = os.path.basename(first_arg).strip() or name processes.append({ "pid": pid, "ppid": ppid, "name": name, "command": command, "cpu_pct": round(cpu, 1), "mem_mb": rss_kb // 1024, "elapsed_secs": elapsed_secs, "elapsed": human_elapsed(elapsed_secs), }) top_processes = sorted(processes, key=lambda p: (p["mem_mb"], p["cpu_pct"]), reverse=True)[:10] ``` The collected command lines are returned in the JSON output: ```python result = { "suspicious": len(issues) > 0, "verdict": verdict, "os": platform.system(), "summary": summary, "issues": issues, "top_processes": top_processes, "ignored_normals": ignored, } print(json.dumps(result, indent=2)) ``` They are also stored for every enumerated process: ```python state = { "timestamp": int(time.time()), "system": { "swap_used_mb": swap_used_mb, ...[truncated 3998 chars]
- Remediation
- ## Remediation Suggestions 1. Stop requesting or retaining full process arguments. Use `comm` for executable identification and collect only PID, PPID, CPU, RSS, and elapsed time. ```python ps_out = run(["ps", "axo", "pid=,ppid=,pcpu=,rss=,etime=,comm="]) ``` 2. Remove the `command` field from `processes`, `top_processes`, anomaly details, and persistent state. Persist only the values required for cross-run comparisons: ```python "processes": { str(p["pid"]): { "mem_mb": p["mem_mb"], "cpu_pct": p["cpu_pct"], "name": p["name"], } for p in processes } ``` 3. If arguments are operationally necessary, make their collection opt-in and redact credential-bearing options, URLs, authorization headers, and environment-like values before output or storage. Prefer an allowlist of explicitly safe arguments over pattern-based removal alone. 4. Create the state directory and file with restrictive permissions. Use directory mode `0700`, write through a temporary file opened with mode `0600`, flush it, and atomically replace the destination. 5. Correct permissions on existing installations and delete previously generated state or log files that may contain secrets. 6. Document that monitoring output must not be sent to untrusted logs or consumers, and run the watchdog with the least-privileged account capable of collecting the required metrics.
