T09 · Insecure Skill Coding Practices
Warning
- Location
- src/douyin/comment-cli.js:151
- Finding
- Automatic Plaintext Retention of Collected Social-Media Data## Vulnerability Details **File Location**: `src/douyin/comment-cli.js:151-162`, `src/douyin/post-cli.js:152-162`, `src/douyin/search-cli.js:253-260`, and `src/utils/log.js:29-35` **Vulnerability Type**: Automatic plaintext storage of potentially sensitive user-generated data **Risk Level**: Medium ### Vulnerable Code `src/douyin/comment-cli.js:151-162`: ```js console.log(JSON.stringify(finalOutput, null, 2)); utils.printSuccess( `获取评论任务完成, 共返回 ${finalOutput.results.length} 条结果`, ); url = url.replace(/[^a-zA-Z0-9_-]/g, ""); url = url.replace("httpswwwdouyincomvideo", ""); url = url.replace("httpswwwdouyincomnote", ""); await log.taskWrite( `${startTime}_${url}_comment.json`, JSON.stringify(finalOutput, null, 2), ); ``` `src/utils/log.js:29-35`: ```js const outputFilename = path.join( path.dirname(__filename), "..", "..", "logs", safeFilename, ); try { await fs.promises.mkdir(path.dirname(outputFilename), { recursive: true }); await fs.promises.writeFile(outputFilename, content); ``` Equivalent automatic persistence occurs for post results in `src/douyin/post-cli.js:152-162` and search results in `src/douyin/search-cli.js:253-260`. ### Technical Analysis Successful search, post, and comment operations serialize the complete result object and automatically write it to a plaintext JSON file under the project-level `logs/` directory. This happens in addition to returning the result through standard output and does not require an explicit output option or separate user confirmation. The stored results may contain comment text, public account identifiers, profile URLs, author metadata, content metadata, and other fields returned by the external API. Because the supported result limit is up to 10,000 records, a single invocation can retain a substantial dataset. `fs.promises.writeFile()` and `fs.promises.mkdir()` are called without explicit restrictive modes. Effecti ...[truncated 1809 chars]
- Remediation
- ## Remediation Suggestions 1. Remove automatic result persistence and return results only through standard output by default. 2. Introduce an explicit opt-in option such as `--output <path>` or `--save`, and clearly notify the user before writing data. 3. When persistence is enabled, create the log directory with mode `0700` and result files with mode `0600`, subject to platform support: ```js await fs.promises.mkdir(logDirectory, { recursive: true, mode: 0o700, }); await fs.promises.writeFile(outputFilename, content, { encoding: "utf8", mode: 0o600, flag: "wx", }); ``` 4. Add configurable retention and deletion controls, including automatic expiration of old files. 5. Minimize stored fields and avoid persisting account identifiers, profile URLs, or comment text unless necessary for the explicitly requested task. 6. Warn users before storing large datasets and document the storage location, contents, permissions, and retention behavior in `SKILL.md`. 7. Consider encryption at rest when persistent storage of collected records is required. 8. Add tests verifying that default execution creates no files and that opt-in files receive restrictive permissions.
