T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/digest.js:13
- Finding
- Persistent Plaintext Storage of Sensitive Personal Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/digest.js:13-14`, `scripts/digest.js:102-106` **Vulnerability Type**: Sensitive data stored persistently without adequate access controls **Risk Level**: Medium ### Vulnerable Code ```javascript const dateStr = new Date().toISOString().split('T')[0]; const logDir = path.join(process.env.USERPROFILE || process.env.HOME, '.openclaw', 'cron', 'DailyDigest_logs'); const logFile = path.join(logDir, `${dateStr}.md`); ``` ```javascript try { if (!fs.existsSync(logDir)) fs.mkdirSync(logDir, { recursive: true }); fs.writeFileSync(logFile, markdownContent); console.log(`Successfully logged digest to: ${logFile}`); ``` The behavior is also explicitly described in `SKILL.md:14-20`: ```markdown 4. **Log & Present**: Use `scripts/digest.js` to assemble these components into a stylized HTML report. **CRITICAL: The script automatically saves this report as a permanent Markdown file in `.openclaw/cron/DailyDigest_logs/[date].md` for historical record.** 5. **Notify User**: Send a brief notification via the `message` tool to the user's active channel. Mention that the full detailed log is available at `.openclaw/cron/DailyDigest_logs/[date].md`. ## Data Sources - **Email**: `himalaya` CLI. - **Calendar**: `gog` CLI. - **News**: Web search or trusted RSS feeds. - **Logs**: Saved locally to `~/.openclaw/cron/DailyDigest_logs/`. ``` ### Technical Analysis The generated report contains email senders and subjects, calendar entries, tasks, and news data. The script writes the complete report to a predictable, persistent Markdown file under the user's home directory. Neither `fs.mkdirSync` nor `fs.writeFileSync` specifies an explicit restrictive filesystem mode. Access therefore depends on the process umask, existing directory permissions, and platform defaults. The implementation also has no retention policy, field-level redaction, encryption, or opt-out control. Reports accumulate by date and may co ...[truncated 1687 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Make historical logging explicitly opt-in rather than mandatory. 2. Create the storage directory with owner-only permissions: ```javascript fs.mkdirSync(logDir, { recursive: true, mode: 0o700 }); ``` 3. Write reports with an explicit owner-only mode: ```javascript fs.writeFileSync(logFile, markdownContent, { encoding: 'utf8', mode: 0o600 }); ``` 4. Check and correct permissions when the directory or destination file already exists. 5. Redact or omit sensitive fields by default, particularly email addresses, subjects, calendar descriptions, and task details. 6. Add a configurable retention period and securely remove reports after expiration. 7. Offer a non-persistent mode that returns the digest without writing it to disk. 8. Clearly notify the user before enabling scheduled permanent storage. 9. Avoid placing these reports in directories synchronized to cloud storage unless the user explicitly requests it. 10. If long-term archives are required, encrypt them using a key managed separately from the report directory. ]]>
