T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/sql_easy.py:580
- Finding
- API Credential and Database Schema Disclosure Through an Unrestricted LLM Endpoint## Vulnerability Details **File Location**: `scripts/sql_easy.py`, lines 115-116 and 580-605 **Vulnerability Type**: Unrestricted transmission of sensitive information to a configurable network endpoint **Risk Level**: High ### Vulnerable Code ```python p_ask.add_argument("--api-key", default=os.getenv("OPENAI_API_KEY", ""), help="LLM API key.") p_ask.add_argument("--base-url", default=os.getenv("OPENAI_BASE_URL", "https://api.openai.com"), help="LLM API base URL.") ``` ```python def call_openai_chat(prompt: str, model: str, api_key: str, base_url: str) -> str: if not api_key: raise SqlEasyError( "Missing OPENAI_API_KEY. Set environment variable or pass --api-key for `ask` command." ) url = base_url.rstrip("/") + "/v1/chat/completions" payload = { "model": model, "temperature": 0, "messages": [ {"role": "system", "content": "Generate safe SQL in JSON output only."}, {"role": "user", "content": prompt}, ], } body = json.dumps(payload).encode("utf-8") req = urlrequest.Request( url=url, data=body, headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", }, method="POST", ) try: with urlrequest.urlopen(req, timeout=60) as resp: resp_payload = json.loads(resp.read().decode("utf-8")) ``` The transmitted prompt is populated with database schema metadata and the user’s question: ```python schema_context = build_schema_context(client, max_tables=max_tables, max_columns=max_columns) if not schema_context.strip(): raise SqlEasyError("Schema discovery returned empty result; cannot generate SQL safely.") prompt = build_nl2sql_prompt(question=question, dialect=client.dialect, schema_context=schema_context) raw = call_openai_chat(prompt=prompt, model=model, a ...[truncated 2540 chars]
- Remediation
- ## Remediation Suggestions 1. Require an `https://` URL and reject plaintext HTTP or unsupported schemes before constructing the request. 2. Allowlist trusted LLM hosts by default, such as the documented provider endpoint. 3. Do not send an `OPENAI_API_KEY` to a non-OpenAI host. Custom providers should use separate, provider-specific credentials. 4. Require explicit user confirmation before sending schema metadata to a custom endpoint. 5. Display the destination host and a concise description of the data being transmitted before the first request. 6. Document clearly in `SKILL.md` that `ask` transmits table names, column names/types, SQL dialect, and the user’s question to an external service. 7. Provide options to redact identifiers, select specific tables, or operate with a manually supplied minimal schema. 8. Consider certificate pinning or organization-controlled proxies in higher-assurance deployments. 9. Avoid passing API keys on the command line where they may be exposed through shell history or process listings; prefer protected environment variables or a credential manager.
