T09 · Insecure Skill Coding Practices
- Location
scripts/llm_provider.py:43- Finding
Silent Cross-Provider Disclosure of Sensitive Task and Learning Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/llm_provider.py:43-58; data originates fromscripts/llm_extract.py:6-13andscripts/llm_transfer.py:5-14,31-48
Vulnerability Type: Unapproved external data transmission caused by automatic provider fallback
Risk Level: HighVulnerable 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
View remediation
Remediation Suggestions
- Remove automatic cross-provider fallback from
call_llm(). Fail closed or use the existing offline heuristic when the selected provider fails. - Never fall back from Ollama to a remote provider unless the user has explicitly enabled remote fallback.
- Add separate configuration such as:
yaml fallback: enabled: false allowed_providers: [] - Require affirmative consent before transmitting persistent learning records to any external provider.
- Display the effective destination before submission, including whether processing is local or remote.
- Fail closed when
config.yamlcannot be parsed. Do not silently replace user configuration with remote-provider defaults. - Validate
provider_type, provider names, and model selections against an explicit allowlist. - Add prompt redaction for common secrets, credentials, tokens, private keys, and sensitive identifiers.
- Minimize submitted content and provide a local-only mode that cryptographically or structurally prevents remote network calls.
- Add tests verifying that an Ollama failure never causes an external request unless explicit remote fallback consent is configured.
- Remove automatic cross-provider fallback from
