T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/skill_earnings_tracker.py:19
- Finding
- Plaintext Storage of Earnings Data Contrary to Encryption Claims<![CDATA[ ## Vulnerability Details **File Location**: `scripts/skill_earnings_tracker.py:19-48`; related security claims in `SKILL.md:159-163` **Vulnerability Type**: Plaintext storage of potentially sensitive financial data with ambient filesystem permissions **Risk Level**: Medium ### Vulnerable Code ```python EARNINGS_DIR = Path.home() / ".openclaw" / "earnings" def ensure_dir(): """Ensure earnings directory exists""" EARNINGS_DIR.mkdir(parents=True, exist_ok=True) def get_log_path(): """Get current month's log file""" today = datetime.now() return EARNINGS_DIR / f"earnings-{today.year}-{today.month:02d}.jsonl" def log_entry(args): """Log an earnings entry""" ensure_dir() entry = { "timestamp": datetime.now().isoformat(), "platform": args.platform, "skill": args.skill, "metric": args.metric, "value": args.value, "period": args.period or datetime.now().strftime("%Y-%m-%d"), "notes": args.notes or "" } log_path = get_log_path() with open(log_path, 'a') as f: f.write(json.dumps(entry) + "\n") ``` The corresponding documentation makes security claims that the implementation does not satisfy: ```markdown ## Security & Privacy - Never log sensitive user data - Credit balances stored in ~/.private/ - API keys not exposed in logs - Earnings data encrypted at rest ``` ### Technical Analysis The application serializes platform names, skill names, metrics, earnings values, dates, and free-form notes directly into unencrypted JSONL files under `~/.openclaw/earnings`. No encryption routine or secure key-management mechanism is present. The implementation also creates the directory and files without explicit permission modes. Their effective permissions therefore depend on the user's current `umask` and existing directory state. On a permissively configured multi-user system, another local account or process may be able to read the stored rec ...[truncated 1618 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Implement authenticated encryption for earnings records if encryption at rest is a functional requirement. Use a maintained cryptographic library and an authenticated construction such as AES-GCM or ChaCha20-Poly1305. 2. Store encryption keys separately from the data. Prefer an operating-system keychain, credential manager, hardware-backed store, or a user-supplied secret. Do not hardcode or save the key beside the encrypted files. 3. Create the storage directory with mode `0700` and each data file with mode `0600`. Validate and correct permissions on pre-existing paths before writing. 4. Consider moving the records to the documented private location, or update `SKILL.md` so that it accurately identifies `~/.openclaw/earnings` as the storage directory. 5. If encryption will not be implemented, remove the “encrypted at rest” claim and clearly disclose that records are stored as plaintext protected only by operating-system filesystem permissions. 6. Warn users not to place credentials, personal data, or other secrets in the free-form `notes` field. 7. Apply similarly restrictive permissions to files produced by the `export` command, because exports contain the complete earnings history in plaintext. 8. Add automated tests verifying storage paths, file permissions, and encryption behavior so future documentation and implementation changes remain consistent. ]]>
