T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/utils/log.js:23
- Finding
- Undisclosed Plaintext Persistence of Collected Data## Vulnerability Details **File Location**: `scripts/utils/log.js:23-34` **Related Call Sites**: `scripts/kuaishou/search-cli.js:204-208`, `scripts/kuaishou/post-cli.js:181-185`, `scripts/kuaishou/comment-cli.js:161-165` **Vulnerability Type**: Automatic plaintext storage of complete API results **Risk Level**: Medium ### Complete Code Snippet ```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); utils.printSuccess(` → 已保存到 ${outputFilename}`); } catch (error) { utils.printError(`日志写入失败: ${error.message}`); } ``` Successful commands pass the complete output object to this function. For example: ```js await log.taskWrite( `${startTime}_${keyword}_${sort}_${time}_${duration}_${limit}_search.json`, JSON.stringify(finalOutput, null, 2), ); ``` Equivalent writes occur in the post and comment command implementations. ### Technical Analysis Every successful collection operation serializes its complete result and automatically creates a persistent file under the project-local `logs/` directory. The stored JSON may contain search keywords, requested profile or video URLs, creator and post information, comments and commenter information, timestamps, and runtime metadata. Search keywords are also incorporated into filenames. Although filename metacharacters and traversal sequences are sanitized, sensitive research terms can remain visible through directory listings. The files are written using the process default permissions. The implementation does not request a restrictive mode such as `0600`, obtain explicit user consent, redact data, impose a retention period, or provide cleanup functionality. The documented output behavior describes structured JSON returned to the caller but does not cle ...[truncated 1539 chars]
- Remediation
- ## Remediation Suggestions 1. Remove automatic result persistence and make stdout-only operation the default. 2. If logging is required, require an explicit opt-in flag such as `--output` or `--save-results`. 3. Clearly disclose what is stored, where it is stored, how long it is retained, and which fields it contains. 4. Write files with restrictive permissions, for example: ```js await fs.promises.writeFile(outputFilename, content, { encoding: "utf8", mode: 0o600, flag: "wx", }); ``` 5. Use a user-selected output directory rather than silently writing inside the package. 6. Avoid embedding keywords or target identifiers in filenames; use random identifiers or non-sensitive timestamps. 7. Support configurable redaction of request URLs, keywords, commenter identifiers, and other unnecessary fields. 8. Add retention limits and a documented cleanup command. 9. Add `logs/` to `.gitignore` to reduce accidental source-control publication. 10. Document the persistence behavior in `SKILL.md` and obtain user approval before saving results.
