T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/llm_provider.py:43
- Finding
- Silent Cross-Provider Disclosure of Sensitive Task and Learning Data## Vulnerability Details **File Location**: `scripts/llm_provider.py:43-58`; data originates from `scripts/llm_extract.py:6-13` and `scripts/llm_transfer.py:5-14,31-48` **Vulnerability Type**: Unapproved external data transmission caused by automatic provider fallback **Risk Level**: High ### Vulnerable Code `scripts/llm_provider.py:43-58`: ```python def call_llm(prompt: str, provider_type: str = "fast", max_tokens: int = 500) -> str | None: """ Call LLM using configured provider. provider_type: "fast" (haiku-level) or "deep" (sonnet-level) Returns text string or None on failure. """ cfg = _load_config() if not cfg: return _fallback(prompt, max_tokens) provider = cfg.get("providers", {}).get(provider_type, "anthropic") model = cfg.get("models", {}).get(provider, {}).get(provider_type, None) env_var = cfg.get("env_vars", {}).get(provider, "") result = _call_provider(provider, model, prompt, max_tokens, env_var) if result is not None: return result # Fallback: try the other provider other_provider = "openai" if provider != "openai" else "anthropic" other_model = cfg.get("models", {}).get(other_provider, {}).get(provider_type) other_env = cfg.get("env_vars", {}).get(other_provider, "") return _call_provider(other_provider, other_model, prompt, max_tokens, other_env) ``` `scripts/llm_transfer.py:5-14`: ```python def get_analogous_principles(task_desc, learnings_content): prompt = f"""Given this task: "{task_desc}" Which of these past learnings are analogically relevant? Explain the connection. Return ONLY valid JSON in this format: {{"principles": [{{"principle": "...", "reasoning": "..."}}]}} Past learnings: {learnings_content}""" result = call_llm(prompt, provider_type="deep", max_tokens=500) ``` `scripts/llm_extract.py:6-13`: ```python def extract_levels(error_desc): prompt ...[truncated 3097 chars]
- Remediation
- ## Remediation Suggestions 1. Remove automatic cross-provider fallback from `call_llm()`. Fail closed or use the existing offline heuristic when the selected provider fails. 2. Never fall back from Ollama to a remote provider unless the user has explicitly enabled remote fallback. 3. Add separate configuration such as: ```yaml fallback: enabled: false allowed_providers: [] ``` 4. Require affirmative consent before transmitting persistent learning records to any external provider. 5. Display the effective destination before submission, including whether processing is local or remote. 6. Fail closed when `config.yaml` cannot be parsed. Do not silently replace user configuration with remote-provider defaults. 7. Validate `provider_type`, provider names, and model selections against an explicit allowlist. 8. Add prompt redaction for common secrets, credentials, tokens, private keys, and sensitive identifiers. 9. Minimize submitted content and provide a local-only mode that cryptographically or structurally prevents remote network calls. 10. Add tests verifying that an Ollama failure never causes an external request unless explicit remote fallback consent is configured.
