T09 · Insecure Skill Coding Practices
- Location
scripts/utils/log.js:5- Finding
Automatic Plaintext Retention of Complete API Results
- Content
View full analysis
|]/g, "_") .replace(/\.\.+/g, "_") .replace(/^\.+|\.+$/g, ""); if (safeFilename.length > 200) { safeFilename = safeFilename.substring(0, 200); } if (safeFilename === "") { safeFilename = `log_${Date.now()}`; } 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}`); } } ``` Every successful search automatically passes the complete response to this utility. The search term and options are also embedded in the filename: ```js const finalOutput = { status: "success", error_code: "OK", message: "搜索任务完成", timestamp: new Date().toLocaleString(), request: { command: "search", keyword: keyword, sort: sort, time: time, duration: duration, limit: limit, }, skill_metadata: { skill_version: constants.VERSION, runtime_version: process ...[truncated 3818 chars]- Remediation
View remediation
` or `--save`. - Continue returning JSON through standard output when no persistence option is supplied. 2. **Use restrictive permissions** - Create the output directory with mode `0o700`. - Create output files with mode `0o600`. - Where supported, use exclusive creation to avoid overwriting files or following unexpected filesystem state: ```js await fs.promises.mkdir(outputDirectory, { recursive: true, mode: 0o700, }); await fs.promises.writeFile(outputFilename, content, { encoding: "utf8", mode: 0o600, flag: "wx", }); ``` 3. **Remove sensitive values from filenames** - Do not include raw search keywords, account identifiers, or video identifiers in filenames. - Use a random identifier or timestamp, such as `search__.json`. - Keep request metadata inside the protected file only when needed. 4. **Support data minimization and redaction** - Allow users to omit request metadata, commenter identifiers, creator identifiers, or other unnecessary fields. - Avoid retaining the complete remote response when only an aggregate or subset is needed. 5. **Implement retention controls** - Provide a configurable expiration period. - Add a cleanup command and document the storage location. - Consider deleting generated files automatically at process completion when they are only temporary. 6. **Clearly disclose persistence** - Document exactly what is written, where it is stored, how long it remains, and how users can disable or delete it. - Obtain explicit user consent before storing complete result datasets. 7. **Consider encryption where archival storage is required** - For sensitive research environments, support encryption using a user-managed key. - Do not embed encryption keys in the Skill package or store them beside encryp ...[truncated 17 chars]
