T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/deliver-briefing.sh:12
- Finding
- Hardcoded QQ Recipient Causes Unauthorized or Misdirected File Delivery<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/deliver-briefing.sh:8-13, 83-93, 108-114` - `scripts/news-deliver-direct.py:45-57, 62-75, 135-143` - Configuration conflict: `README.md:22-29`, `SKILL.md:63-73`, `references/CONFIGURATION.md:16-17` **Vulnerability Type**: Hardcoded outbound recipient and ignored security-sensitive configuration **Risk Level**: High ### Vulnerable Code The shell delivery script embeds a fixed QQ user identifier: ```bash # Configuration TODAY=$(date +"%Y%m%d") NEWS_FILE="/root/.openclaw/workspace/daily-news-${TODAY}.md" LOG_FILE="/var/log/news-delivery.log" TARGET_USER="9C12E02D9038B14FCEDCE1B69AAEAB3F" TIMEOUT=30 ``` It constructs a file attachment and sends it to that fixed identifier: ```bash DELIVERY_MESSAGE="📰 早安,Sir! 今日简报已送达 - ${MONTH_DAY} 🖥️ 科技要闻:${TECH_HEADLINE} 📈 财经动态:${FINANCE_HEADLINE} 完整报告见附件:<qqfile>${NEWS_FILE}</qqfile> ⏰ 明日同一时间自动推送 • Jarvis Daily Briefing" ``` ```bash if timeout $TIMEOUT openclaw message send \ --channel qqbot \ -t "qqbot:c2c:${TARGET_USER}" \ -m "$ESCAPED_MESSAGE" 2>>"$LOG_FILE"; then ``` The alternative Python delivery path independently embeds the same recipient and accepts a caller-supplied file path: ```python def create_delivery_message(news_file): """Create the delivery message with file attachment.""" month_day = datetime.date.today().strftime('%m月%d日') tech_hl, finance_hl = extract_headlines(news_file) message = f"""📰 早安,Sir! 今日简报已送达 - {month_day} 🖥️ 科技要闻:{tech_hl}... 📈 财经动态:{finance_hl}... 完整报告:<qqfile>{news_file}</qqfile> ⏰ 明日同一时间自动推送 • Jarvis Daily Briefing""" return message ``` ```python def send_via_openclaw_cli(message, target): """Send message using OpenClaw CLI.""" try: cmd = [ 'openclaw', 'message', 'send', '--channel', 'qqbot', '-t', f'c2c:{target}', '-m', message ] result = subprocess.run( cmd, ...[truncated 4075 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Remove every embedded recipient identifier.** Read the destination exclusively from a clearly documented environment variable or a protected configuration file: ```bash : "${NEWS_TARGET_USER:?NEWS_TARGET_USER must be configured}" NEWS_CHANNEL="${NEWS_CHANNEL:-qqbot}" TARGET_USER="$NEWS_TARGET_USER" ``` 2. **Fail closed when no recipient is configured.** Do not retain a default third-party account. Print the selected channel and masked recipient and require an explicit test before scheduled operation. 3. **Use one consistent variable name.** Replace the conflicting `NEWS_TARGET_USER` and `QQ_TARGET_USER` documentation with a single canonical setting used by both scripts. 4. **Validate destination format by channel.** Apply an allowlist for supported channel names and enforce the expected identifier syntax before invoking OpenClaw. 5. **Restrict Python attachments to generated reports.** Resolve paths canonically and require a regular file beneath the expected workspace with the expected filename pattern: ```python from pathlib import Path workspace = Path("/root/.openclaw/workspace").resolve() news_file = Path(news_file).resolve() if ( news_file.parent != workspace or not news_file.is_file() or not re.fullmatch(r"daily-news-\d{8}\.md", news_file.name) ): raise ValueError("Attachment is not an approved generated briefing") ``` 6. **Require explicit authorization for arbitrary attachments.** If arbitrary-file delivery is intentional, expose it as a separate command with a confirmation prompt and a configurable path allowlist. 7. **Avoid unnecessary secondary scheduling.** The Python fallback should attempt direct delivery before creating an OpenClaw cron task. If a one-time task is created, give it an expiration policy and verify that it is removed after execution. 8. **Add automated tests.** Tests should verify that: - The documented environment recip ...[truncated 245 chars]
