T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/download_signals.py:105
- Finding
- Cloud identifier disclosure occurs before cloud synchronization consent<![CDATA[ ## Vulnerability Details **File Location**: `scripts/session_hook.py:157-177`, `scripts/upload_signals.py:121-139, 274-279`, and `scripts/download_signals.py:105-120` **Vulnerability Type**: Consent bypass and persistent identifier disclosure **Risk Level**: High ### Vulnerable Code ```python def cmd_start(skill_dir): name = os.path.basename(skill_dir.rstrip("/\\")) if not os.path.exists(os.path.join(skill_dir, SIGNALS_MD)): print(f"[session] [{name}] Non-signal skill, skipped") return 0 try: subprocess.run([sys.executable, os.path.join(HERE, "upload_signals.py")], capture_output=True, timeout=120) except Exception: pass try: subprocess.run([sys.executable, os.path.join(HERE, "download_signals.py"), "pull", "--dir", skill_dir], capture_output=True, timeout=120) except Exception: pass cmd_begin(skill_dir) return 0 ``` The upload process creates a persistent identifier before checking cloud consent: ```python created = bootstrap(skill_dir) if created: log(f"[{name}] bootstrap created state files: {', '.join(created)}") cloud_optin = read_state_file(os.path.join(skill_dir, ".cloud_optin")) if cloud_optin == "off": log(f"[{name}] .cloud_optin=off, cloud upload skipped") return 0, [] ``` The subsequent download process does not inspect `.cloud_optin`: ```python anon_id = _read_file(os.path.join(skill_dir, ".anon_id")) if not anon_id: print("[download] No .anon_id, synchronization skipped") return 0 base = resolve_aggregate_url(skill_dir) if not base: print("[download] Aggregate endpoint not configured") return 0 url = f"{base}{RESTORE_PATH}?anon_id={anon_id}" req = urllib.request.Request(url, method="GET") try: with urllib.request.urlopen(req, timeout=15) as resp: data = json.loads(resp.read().decode("utf-8")) ``` ### Technical Analysis The documented consent model states that cloud ...[truncated 1794 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Check `.cloud_optin` before creating `.anon_id` or invoking any cloud-related subprocess. 2. Add an independent consent check at the beginning of `download_signals.py` so it remains safe when called directly. 3. Do not invoke either upload or download logic from `session_hook.py` unless cloud synchronization is explicitly enabled. 4. Send identifiers in a request body or authenticated header rather than a query string. 5. Separate local telemetry initialization from cloud synchronization initialization. 6. Add regression tests proving that no DNS lookup, socket connection, or HTTP request occurs while `.cloud_optin` is absent or set to `off`. 7. Rotate existing identifiers if they may already have been disclosed without consent. ]]>
