T09 · Insecure Skill Coding Practices
- Location
scripts/generate_tts.py:95- Finding
User-Controlled API Endpoint Can Disclose the DashScope API Key
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly performs Alibaba Cloud text-to-speech, but it lets request data change the API endpoint before using the user's API key, which could expose the key and submitted text.
Review this skill before installing. Run it only in an isolated virtual environment with a tightly scoped DashScope API key, use request files you control, avoid any `base_url` override, keep outputs in a dedicated directory, and delete saved request/audio artifacts if they contain private text or voice content. Pin the DashScope SDK version before operational use.
scripts/generate_tts.py:95User-Controlled API Endpoint Can Disclose the DashScope API Key
scripts/generate_tts.py:108Unvalidated Audio URL Enables Arbitrary Network Retrieval and Unbounded Downloads
SKILL.md:37Unpinned DashScope Dependency Creates Supply-Chain Exposure
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
def download_audio(audio_url: str, output_path: Path) -> None:
output_path.parent.mkdir(parents=True, exist_ok=True)
with urllib.request.urlopen(audio_url) as response:
output_path.write_bytes(response.read())
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def _load_env() -> None:
_load_dotenv(Path.cwd() / ".env")
repo_root = _find_repo_root(Path(__file__).resolve())
if repo_root:
_load_dotenv(repo_root / ".env")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def _load_env() -> None:
_load_dotenv(Path.cwd() / ".env")
repo_root = _find_repo_root(Path(__file__).resolve())
if repo_root:
_load_dotenv(repo_root / ".env")
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
_load_dashscope_api_key_from_credentials()
if not os.environ.get("DASHSCOPE_API_KEY"):
print(
"Error: DASHSCOPE_API_KEY is not set. Configure it via env/.env or ~/.alibabacloud/credentials.",
file=sys.stderr,
)
print("Example .env:\n DASHSCOPE_API_KEY=your_key_here", file=sys.stderr)
The skill documents capabilities that involve environment access, filesystem reads/writes, and outbound network use, but it does not declare any explicit tool scope or permissions boundary. In an agent setting, this weakens least-privilege controls and makes it easier for the skill to be executed with broader access than necessary, increasing the blast radius if the skill is misused or later modified.
The validation and output guidance create persistent artifacts under a fixed output directory, including logs and generated files. In this skill's context, persistence is more sensitive because the artifacts can include request payloads and audio derived from user-provided text, which may contain confidential or personal information and remain accessible beyond the session.
mkdir -p output/alicloud-ai-audio-tts
python -m py_compile skills/ai/audio/alicloud-ai-audio-tts/scripts/generate_tts.py && echo "py_compile_ok" > output/alicloud-ai-audio-tts/validate.txt
The skill instructs users to save request payloads, generated audio links, and sample audio artifacts without warning that these may contain sensitive text, personal data, or confidential voice content. Persisting such artifacts by default can create an avoidable data exposure risk through logs, shared workspaces, backups, or later reuse.
The script allows an arbitrary base_url from untrusted request input to override the DashScope API endpoint. This broadens the tool from a DashScope-only TTS client into a generic outbound HTTP client and can redirect requests, including the API key, to attacker-controlled infrastructure.
The markdown instructs users to set DASHSCOPE_API_KEY in the environment or place dashscope_api_key in ~/.alibabacloud/credentials. Although expected for authentication, there is no caution about protecting the key, avoiding commits/logging, or securing the credentials file.
The sample request sets language_type="English" directly in the example. This may encourage implementations that force a language choice rather than deriving it from user preference or asking for confirmation.
The file title and heading are written only in Chinese ('官方文档来源(用于后续更新)') with no indication that the skill supports other languages or that Chinese is a required locale. This creates a natural-language locale constraint without user opt-in or documented justification, which matches the policy-violation category.
This code performs a filesystem write by creating parent directories and saving remote content to the provided output path. Although the script's purpose is TTS generation, there is no explicit warning that an existing file at that path may be overwritten or that network-fetched data will be written locally.
No suspicious patterns detected.