T09 · Insecure Skill Coding Practices
- Location
send-sms.sh:58- Finding
Arbitrary Shell Command Execution Through Sourced .env File
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This SMS skill does what it advertises, but its credential handling and endpoint controls are unsafe enough to require review before installation.
Install only if you are comfortable reviewing or hardening the script first. Prefer OpenClaw-managed secrets, avoid the .env file path, do not run it from a writable or shared skill directory, and ensure SMS credentials can only be sent to the official Chuanglan HTTPS endpoint.
send-sms.sh:58Arbitrary Shell Command Execution Through Sourced .env File
send-sms.sh:82Credential Exfiltration Through Unrestricted API Endpoint Override
send-sms.sh:99JSON Injection and Request Corruption Through Unescaped Arguments
SKILL.md:50Plaintext Credential File Guidance Without Permission Hardening
The documentation instructs users to write the SMS account credential into a local .env file inside the skill directory. Storing secrets in a plaintext file increases the risk of accidental disclosure through permissive file permissions, backups, syncing, local compromise, or inadvertent inclusion in archives or repositories.
cd ~/.claude/skills/sms-chuanglan
echo "CHANGLAN_ACCOUNT=你的API账号" > .env
echo "CHANGLAN_PASSWORD=你的API密码" >> .env
This line continues the plaintext .env credential storage pattern by appending the API password to a file in the skill directory. Passwords stored this way are easier to leak through filesystem access, debugging artifacts, sync services, backups, or source-control mistakes, especially because the skill docs normalize this insecure pattern.
cd ~/.claude/skills/sms-chuanglan
echo "CHANGLAN_ACCOUNT=你的API账号" > .env
echo "CHANGLAN_PASSWORD=你的API密码" >> .env
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env"
usage() {
echo "用法: send-sms.sh --phone <手机号> --template <模板ID> [--vars <变量JSON>]"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
usage
fi
# 读取配置(优先环境变量,其次 .env 文件)
load_config() {
# 优先使用环境变量
if [[ -z "$CHANGLAN_ACCOUNT" ]] || [[ -z "$CHANGLAN_PASSWORD" ]]; then
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
usage
fi
# 读取配置(优先环境变量,其次 .env 文件)
load_config() {
# 优先使用环境变量
if [[ -z "$CHANGLAN_ACCOUNT" ]] || [[ -z "$CHANGLAN_PASSWORD" ]]; then
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
usage
fi
# 读取配置(优先环境变量,其次 .env 文件)
load_config() {
# 优先使用环境变量
if [[ -z "$CHANGLAN_ACCOUNT" ]] || [[ -z "$CHANGLAN_PASSWORD" ]]; then
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
usage
fi
# 读取配置(优先环境变量,其次 .env 文件)
load_config() {
# 优先使用环境变量
if [[ -z "$CHANGLAN_ACCOUNT" ]] || [[ -z "$CHANGLAN_PASSWORD" ]]; then
Using source on a .env file executes the file as shell code rather than safely parsing key-value pairs. If an attacker can modify that file, they can achieve arbitrary command execution when the script runs, making this substantially more dangerous than ordinary secret loading.
load_config() {
# 优先使用环境变量
if [[ -z "$CHANGLAN_ACCOUNT" ]] || [[ -z "$CHANGLAN_PASSWORD" ]]; then
# 尝试读取 .env 文件
if [[ -f "$ENV_FILE" ]]; then
source "$ENV_FILE"
fi
The skill advertises and depends on shell-capable binaries (curl, jq, openssl) but does not declare an explicit tool/permission scope. That creates an avoidable trust gap: consumers and platforms cannot clearly constrain or review what execution capabilities the skill expects, increasing the chance of unintended command execution or overbroad runtime access.
This skill sends phone numbers, template identifiers, and variable content to an external SMS provider, yet the documentation does not clearly warn that personal data and potentially sensitive message contents leave the local environment. Users may unknowingly transmit PII, OTPs, or business-sensitive data to a third party without considering privacy, consent, retention, or compliance requirements.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
fi
# 调用 API
local response=$(curl -s -m 30 -X POST "${CHANGLAN_API_URL}" \
-H "Content-Type: application/json" \
-d "${request_body}")
The script sends the recipient phone number, account identifier, and password in an HTTP POST request to a third-party SMS service. Although the script's purpose is to send SMS, there is no explicit warning, confirmation, or prior disclosure in the file that sensitive user data and credentials will be transmitted off-host.
All usage/help and error messaging in the script is hard-coded in Chinese, and the file provides no option to select another language or indicate that the script is intentionally limited to Chinese-speaking users. This is a natural-language policy concern because it enforces a specific locale without user choice or documented justification.
The manifest description and command metadata are written only in Chinese, which can impose a language constraint on users without any opt-in or documented justification. Under the policy rule, language or locale restrictions should either offer user choice or clearly state a justified region-specific scope.
No suspicious patterns detected.