T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/api_key_validator.py:39
- Finding
- DeepSeek Credentials Can Be Misclassified and Transmitted to OpenAI<![CDATA[ ## Vulnerability Details **File Location**: `scripts/api_key_validator.py`, lines 39-47, 58-61, and 92-99 **Vulnerability Type**: Credential disclosure caused by ambiguous provider detection **Risk Level**: Critical ### Vulnerable Code ```python KEY_PATTERNS = { "OpenAI": r"^sk-(proj-)?[A-Za-z0-9_-]{30,}$", "Tavily": r"^tvly-[A-Za-z0-9-]{20,}$", "Notion": r"^ntn_[A-Za-z0-9]{20,}$", "GitHub": r"^gh[pousr]_[A-Za-z0-9]{20,}$", "DeepSeek": r"^sk-[A-Za-z0-9_-]{20,}$", "Feishu": r"^[A-Za-z0-9]{24,}$", "Generic": r"^[A-Za-z0-9_-]{16,}$", } def detect_key_type(key: str) -> dict: if not key: return {"key_type": "Unknown"} cleaned = key.strip() for ktype, pattern in KEY_PATTERNS.items(): if re.match(pattern, cleaned): return {"key_type": ktype} return {"key_type": "Unknown"} def validate_openai_key(key: str, label: str = "OpenAI") -> dict: """Test OpenAI API key by listing models (cheapest endpoint).""" url = "https://api.openai.com/v1/models" try: req = urllib.request.Request(url, method="GET") req.add_header("Authorization", f"Bearer {key}") req.add_header("User-Agent", "OpenClaw-Autofix/6.0") start = time.time() with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp: ... ``` ### Technical Analysis OpenAI and DeepSeek credentials use overlapping `sk-` formats. Because Python dictionaries preserve insertion order and the OpenAI regular expression is evaluated before the DeepSeek expression, a DeepSeek key containing at least 30 characters after `sk-` is classified as an OpenAI key. The dispatch logic subsequently calls `validate_openai_key`, which places the complete credential in an HTTP Authorization header and sends it to `https://api.openai.com/v1/models`. The destination is unrelated to the service that issued the credential. This behavior is especially significant because `diagnosis_formatter.py` inv ...[truncated 1045 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Determine the provider from the configuration structure, such as `providers.deepseek.apiKey`, rather than from an overlapping token prefix. 2. Replace first-match regular-expression classification with an explicit provider-to-credential mapping. 3. Treat ambiguous `sk-` credentials as unknown and skip online validation. 4. Require explicit user consent before sending any credential to a remote provider. 5. Display the exact destination hostname before validation without displaying the credential. 6. Add tests proving that DeepSeek credentials can never reach an OpenAI endpoint. 7. Make offline format validation the default and expose network validation through a separate opt-in flag such as `--online`. ]]>
