T09 · Insecure Skill Coding Practices
- Location
SKILL.md:24- Finding
Plaintext Persistence of Reusable DingTalk Credentials and Access Tokens
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 24–28, 35–38, 53–60, and 73–75
Vulnerability Type: Plaintext sensitive-data storage
Risk Level: MediumVulnerable Code
markdown 2. **读取配置** → 用一条 `grep -E '^KEY1=|^KEY2='` 命令一次性读取该通道所需的全部键值,不要分多次查询。 3. **仅收集该通道所需的缺失配置** → 一次性询问,不要逐条问 4. **持久化** → 写入 config,后续无需再问markdown | Webhook | `DINGTALK_WEBHOOK_URL` | 群设置 → 智能群助手 → 添加自定义机器人 | | Webhook(加签) | 额外 `DINGTALK_WEBHOOK_SECRET` | 创建机器人时选择"加签"模式获得 | | 机器人消息 | `DINGTALK_APP_KEY` + `DINGTALK_APP_SECRET` | 开放平台 → 应用管理 → 凭证信息 |bash CONFIG=~/.dingtalk-skills/config # 一次性读取所有所需配置 APP_KEY=$(grep '^DINGTALK_APP_KEY=' "$CONFIG" | cut -d= -f2-) APP_SECRET=$(grep '^DINGTALK_APP_SECRET=' "$CONFIG" | cut -d= -f2-) # Token 缓存:有效期内复用,避免重复请求 CACHED_TOKEN=$(grep '^DINGTALK_ACCESS_TOKEN=' "$CONFIG" 2>/dev/null | cut -d= -f2-) TOKEN_EXPIRY=$(grep '^DINGTALK_TOKEN_EXPIRY=' "$CONFIG" 2>/dev/null | cut -d= -f2-)bash sed -i '/^DINGTALK_ACCESS_TOKEN=/d;/^DINGTALK_TOKEN_EXPIRY=/d' "$CONFIG" echo "DINGTALK_ACCESS_TOKEN=$TOKEN" >> "$CONFIG" echo "DINGTALK_TOKEN_EXPIRY=$EXPIRY" >> "$CONFIG"Technical Analysis
The skill instructs the agent to retain DingTalk application secrets, signing secrets, credential-bearing webhook URLs, and access tokens in
~/.dingtalk-skills/config. These values constitute reusable authentication material:DINGTALK_APP_SECRETcan be used with the application key to obtain access tokens.DINGTALK_WEBHOOK_SECRETpermits generation of valid webhook signatures.DINGTALK_WEBHOOK_URLembeds a webhook access token.DINGTALK_ACCESS_TOKENdirectly authorizes DingTalk API requests until expiration.
The documented workflow does not require restrictive directory or file permissions, ownership validation, a secure credential store, or protection from symbolic-link attacks when editing the configuration file. It also persists short-lived access tokens even though they can be obtained when needed ...[truncated 1688 chars]
- Remediation
View remediation
Remediation Suggestions
- Store long-lived credentials in an operating-system keychain, managed secret store, or injected environment variables rather than a shared plaintext configuration file.
- Do not persist access tokens unless operationally necessary. Obtain them when required and retain them only in process memory.
- If file-based storage is unavoidable:
- Create
~/.dingtalk-skillswith mode0700. - Create the configuration file with mode
0600. - Set
umask 077before creating temporary or configuration files. - Verify that the file is owned by the current user and is not a symbolic link before reading or modifying it.
- Reject files with group or world permissions.
- Create
- Separate non-sensitive configuration from secrets and avoid storing webhook URLs in logs, command histories, or backups.
- Update credentials atomically through a securely created temporary file rather than direct append operations.
- Document credential rotation and revocation procedures for application secrets, webhook tokens, and signing secrets.
- Continue redacting credentials in output, but treat this only as an additional safeguard rather than a replacement for secure storage.
