T09 · Insecure Skill Coding Practices
- Location
SKILL.md:71- Finding
Hardcoded Shared UniSound API Credentials
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This TTS skill mostly matches its stated purpose, but it exposes shared API credentials and grants/uses broader execution and network authority than the task needs.
Install only after replacing the published UniSound credentials with your own, removing or tightly validating the custom --url option, redacting signed URLs from logs, and narrowing agent permissions to the exact TTS command. Use a virtual environment with pinned dependencies and avoid sending sensitive text to the service.
SKILL.md:71Hardcoded Shared UniSound API Credentials
scripts/tts.py:299User-Controlled WebSocket Destination Enables Sensitive Data Redirection
scripts/tts.py:174Authentication-Bearing WebSocket URL Is Written to Logs
requirements.txt:4Unpinned and Unnecessary Third-Party Dependencies Expand Supply-Chain Risk
.claude/settings.local.json:3Wildcard Python Permission Enables Arbitrary Command Execution
The skill includes concrete AppKey and Secret values and instructs users to place them in a .env file. Publishing usable secrets in documentation is credential exposure: anyone reading the skill can reuse them, abuse the vendor account, and potentially access or submit data through the associated API.
python scripts/tts.py --text '你好'
**Method 2: .env File (Recommended for Development)**
Create a `.env` file in the project root:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
**使用环境变量**——安全地将凭据存储在环境变量中
- **Never hardcode credentials** - Don't embed production credentials in code
**切勿硬编码凭据**——不要在代码中嵌入生产凭据
- **Use .env files** - For local development (add to .gitignore)
**使用 .env 文件**——用于本地开发(添加到 .gitignore)
- **Rotate credentials regularly** - In production environments
**定期轮换凭据**——在生产环境中
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
**使用环境变量**——安全地将凭据存储在环境变量中
- **Never hardcode credentials** - Don't embed production credentials in code
**切勿硬编码凭据**——不要在代码中嵌入生产凭据
- **Use .env files** - For local development (add to .gitignore)
**使用 .env 文件**——用于本地开发(添加到 .gitignore)
- **Rotate credentials regularly** - In production environments
**定期轮换凭据**——在生产环境中
The skill declares required environment variables and directs the agent to use credentials, but does not define any explicit tool scope such as permissions or allowed-tools. That omission can let a runtime grant broader-than-necessary access to environment data or execution capabilities, violating least privilege and making credential-bearing operations harder to constrain.
The instructions say to ONLY use UniSound TTS, NEVER offer alternatives, and STOP immediately on failure. Combined with the skill description's focus on Chinese Mandarin, this prevents offering language or locale choice to the user and imposes a fixed language/tool path without opt-in.
The dependency is specified with only a lower bound, so builds may resolve to different versions over time. This creates supply-chain and reproducibility risk because a later vulnerable or malicious release could be installed without review.
# U2-TTS Requirements
# Core dependency
websocket-client>=0.56.0
# Optional: For async operations
gevent>=1.4.0
The gevent dependency is unpinned, which means the environment may install an unpredictable version. In this case the risk is more meaningful because gevent has known advisories in some versions, so lack of pinning makes it unclear whether deployments are exposed.
websocket-client>=0.56.0
# Optional: For async operations
gevent>=1.4.0
# Dependencies (auto-installed with gevent)
greenlet>=0.4.15
The manifest includes gevent without pinning a version, and advisories exist for some gevent releases. Because this skill performs networked, real-time WebSocket-based processing, an affected gevent version could increase exposure to remotely triggered issues or privilege-related flaws in environments where gevent is installed and used.
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
gevent>=1.4.0
# Dependencies (auto-installed with gevent)
greenlet>=0.4.15
cffi>=1.12.3
pycparser>=2.19
six>=1.12.0
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
# Dependencies (auto-installed with gevent)
greenlet>=0.4.15
cffi>=1.12.3
pycparser>=2.19
six>=1.12.0
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
# Dependencies (auto-installed with gevent)
greenlet>=0.4.15
cffi>=1.12.3
pycparser>=2.19
six>=1.12.0
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
greenlet>=0.4.15
cffi>=1.12.3
pycparser>=2.19
six>=1.12.0
This code sets a Chinese default input string ('今天天气怎么样?') and targets a Chinese TTS endpoint/voice configuration, which creates a language-specific default behavior. The file does not state that Chinese is required or offer locale/language selection as a policy choice beyond voice selection, so the default appears to force a specific language context without explicit opt-in.
The --no-cleanup argument is documented as controlling cleanup of old log files, but the script contains no corresponding log cleanup logic anywhere. This creates an intent/documentation mismatch by claiming behavior that the implementation does not perform.
No suspicious patterns detected.