T09 · Insecure Skill Coding Practices
- Location
src/generator.py:251- Finding
Hardcoded DashScope API Credential and Misleading Client Activation
- Content
View full analysis
Vulnerability Details
File Location:
src/generator.py:251-296
Vulnerability Type: Hardcoded secret and unintended remote API activation
Risk Level: HighThe generator contains a plaintext DashScope API key. Although the command-line entry point creates the generator without a client and therefore uses local mock generation, library callers can activate the remote request by passing any truthy value as
client. The supplied client object is not actually used to perform the request.Vulnerable Code
Remote generation is activated based only on the truthiness of
self.client:python if self.client: response = self._call_llm( system=template["system"], user=user_prompt ) else: response = self._mock_generate(request)The activated method uses a credential embedded directly in the source:
python api_key = "sk-sp-1f1d92cdff7d4cbd8dcbe1cd08711606" url = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions" data = { "model": "qwen3.5-plus", "messages": [ {"role": "system", "content": system}, {"role": "user", "content": user} ], "temperature": 0.7, "max_tokens": 2000 } req = urllib.request.Request( url, data=json.dumps(data).encode('utf-8'), headers={ 'Content-Type': 'application/json', 'Authorization': f'Bearer {api_key}' } ) with urllib.request.urlopen(req, timeout=30) as response: result = json.loads(response.read().decode('utf-8')) content = result['choices'][0]['message']['content'] return content.strip()Technical Analysis
Secrets embedded in source code become available to every person or system that can read the project, including users who download the Skill, source-control users, build systems, backups, and artifact scanners. The key cannot be considered confidential after distribu ...[truncated 2974 chars]
- Remediation
View remediation
Remediation Suggestions
-
Revoke and rotate the exposed credential immediately.
- Treat the displayed key as compromised even if there is no confirmed abuse.
- Review provider logs, billing records, quota usage, source-control history, build artifacts, and published packages for unauthorized use.
-
Remove the credential from all source and artifact history.
- Delete the literal from the current source.
- Purge it from repository history and previously published artifacts where practical.
- Do not assume deleting it from the latest revision restores confidentiality.
-
Use secure external configuration.
- Read the credential from an environment variable such as
DASHSCOPE_API_KEYor from a dedicated secret manager. - Never log, print, serialize, or include the credential in exceptions.
- Apply provider-side restrictions, minimal permissions, quotas, and expiration where supported.
- Read the credential from an environment variable such as
-
Correct the client interface.
- If callers supply a client, invoke that client's documented generation method directly.
- Alternatively, remove the generic
clientargument and replace it with an explicit provider configuration or anenable_remote_generationoption. - Do not use an arbitrary object merely as a Boolean switch for a different hardcoded client.
-
Make remote transmission explicit and fail safely.
- Keep generation offline by default.
- Require explicit configuration and user consent before transmitting prompts.
- If remote generation is requested without a credential, return a clear configuration error rather than silently selecting a shared secret.
- Document exactly which fields are transmitted and to which service.
-
Align documentation with implementation.
- Update
README.mdandSKILL.mdto disclose the conditional network request. - Remove statements implying that real LLM integration is still pending if the feature r ...[truncated 338 chars]
- Update
-
