Back to skill

Security audit

Skill Earnings Tracker

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but it stores and exports earnings records in plaintext while claiming the data is encrypted.

Review this skill before installing if you plan to track real earnings, credits, customer information, or private notes. Treat ~/.openclaw/earnings and exported reports as plaintext files, avoid entering secrets or personal data in notes, and protect or delete exports manually.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

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. ]]>
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Session Persistence

Medium
Category
Rogue Agent
Content
### Month 2+: Scale
- Cross-promote on social
- Create companion skills
- Consider premium tier

## Security & Privacy
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
import subprocess
    
    try:
        result = subprocess.run(
            ["clawhub", "explore", "--limit", "100"],
            capture_output=True,
            text=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The skill explicitly describes persistent local storage of earnings data and an export function, but it does not clearly warn users that these files may contain sensitive business information and will remain on disk unless manually protected or deleted. While the data is not obviously high-risk personal data, marketplace revenue, usage, and portfolio information can still be sensitive and may be exposed through weak filesystem permissions, backups, or accidental sharing of exported files.

Static analysis

No suspicious patterns detected.