T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:73
- Finding
- Automatic Plaintext Persistence of Sensitive User Profile Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:73-88`, `fortune_rules.md:295-324`, and `user_chart_profile.md:37` **Vulnerability Type**: Automatic storage of sensitive personal data in plaintext without explicit consent or adequate protection **Risk Level**: Medium ### Evidence The skill requires profile initialization when a user provides a chart for the first time: ```text When the user provides a chart for the first time, perform one initialization and profile-creation operation. Initialization procedure: 1. Extract and organize fields from the chart text supplied by the user. 2. Generate a structured profile and write it to: - {baseDir}/user_chart_profile.json 3. Record the update timestamp and schema version. 4. If the user requests an update, reset, or replacement, overwrite the JSON file and recreate the profile. ``` The deterministic rules also allow profile creation to be triggered merely by detecting complete chart text and define storage of the unredacted input: ```json { "profileVersion": "1.0.0", "updatedAt": "<YYYY-MM-DDTHH:mm:ss+08:00>", "basic": { "gender": "<value>", "clockTime": "<YYYY-MM-DD HH:mm>", "trueSolarTime": "<YYYY-MM-DD HH:mm>", "lunarTime": "<value>", "baziJieqi": "<value>", "baziNonJieqi": "<value>", "mingZhu": "<value>", "shenZhu": "<value>" }, "chartRaw": "<raw chart text>", "chartSummary": "<structured summary>" } ``` The profile template separately warns that real profile data should only be generated in a private local environment and should not be committed to the repository: ```text If a real profile is written, generate it in a private local environment and avoid committing it to the repository. ``` ### Technical Analysis The skill automatically writes user-supplied chart information to `{baseDir}/user_chart_profile.json` when a complete chart is detected. The stored data may include gender, exact birth-related timestamps, lunar and astrological bir ...[truncated 2741 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Require explicit opt-in before persistence** - Treat chart submissions as session-only by default. - Present a clear consent prompt before creating a persistent profile. - Explain what fields will be stored, where they will be stored, and how the user can delete them. 2. **Minimize stored data** - Do not retain `chartRaw` by default. - Store only the normalized fields and derived scores required for future calculations. - Allow raw-text retention only through a separate, explicit opt-in. 3. **Use private application storage** - Store profiles in a host-managed, per-user private data directory rather than `{baseDir}`. - Prevent profile sharing between users or tenants. - Require owner-only file permissions where the platform supports them. 4. **Protect data at rest** - Use a platform secret store or encrypted profile storage when available. - Avoid writing sensitive data if secure storage is unavailable; use session-only memory instead. 5. **Implement a defined retention policy** - Add automatic expiration or a configurable retention period. - Provide a deterministic deletion operation that removes the file rather than only marking it inactive. - Confirm successful deletion to the user. 6. **Prevent accidental publication** - Add `user_chart_profile.json` and equivalent generated profile files to source-control ignore rules. - Add a startup check that warns if a generated profile is inside a repository or shared skill installation. 7. **Resolve documentation conflicts** - Make `SKILL.md`, `fortune_rules.md`, and `user_chart_profile.md` consistently require explicit consent and private storage. - Remove the automatic trigger based solely on detecting complete chart text. ]]>
