T09 · Insecure Skill Coding Practices
Warning
- Location
- scheduler.py:384
- Finding
- Plaintext Persistence of User Request Content## Vulnerability Details **File Location**: `scheduler.py:384-390` and `resource_locator.py:332-342` **Vulnerability Type**: Plaintext storage of potentially sensitive user input **Risk Level**: Medium ### Vulnerable Code `scheduler.py:384-390`: ```python self.stats_collector.record({ 'input': user_input[:100], 'complexity': complexity.value, 'latency_ms': result.latency_ms, 'success': result.success }) ``` `resource_locator.py:332-342`: ```python def __init__(self, db_path: str = "/home/admin/.openclaw/workspace/data/scheduler_stats.jsonl"): self.db_path = db_path os.makedirs(os.path.dirname(db_path), exist_ok=True) def record(self, stats: Dict): """记录统计""" import time stats['timestamp'] = time.time() with open(self.db_path, 'a') as f: f.write(json.dumps(stats, ensure_ascii=False) + '\n') ``` ### Technical Analysis Every request handled by `SmartScheduler.handle()` has its first 100 characters included in a statistics record. `StatsCollector.record()` then appends that record to a persistent JSONL file at a fixed local path. The request content is stored without secret detection, redaction, encryption, an explicit retention policy, or an opt-out mechanism. The file is also opened without explicitly enforcing a restrictive permission mode. Consequently, its effective access permissions depend on the process umask and existing file permissions. The stored prefix may contain passwords, API tokens, personal information, customer data, source code, or other confidential content. Although only the first 100 characters are retained, users commonly place credentials and essential context near the beginning of requests. ### Attack Path 1. A user submits a scheduler request whose first 100 characters contain sensitive information. 2. `SmartScheduler.handle()` copies that prefix into the `input` statistics field. 3. `StatsCollector.record()` appends the complete record to `scheduler_stats.jsonl`. 4. Records acc ...[truncated 980 chars]
- Remediation
- ## Remediation Suggestions 1. Remove raw user input from telemetry by default. Store only non-content metrics such as complexity, latency, and success status. 2. If request correlation is necessary, use a random request identifier rather than the request text. 3. If content retention is a required feature, obtain explicit user or administrator consent and document what is collected, why it is collected, and how long it is retained. 4. Apply structured redaction before persistence. Detect and remove credentials, authorization headers, API keys, passwords, tokens, personal identifiers, and other sensitive fields. 5. Implement bounded retention through record limits, time-based expiration, and secure deletion or rotation. 6. Use a configurable data path instead of a hard-coded account-specific location. 7. Create the statistics file with owner-only permissions, such as mode `0600`, and verify that the containing directory is not accessible to unrelated users. 8. Encrypt retained sensitive data at rest using a properly managed key if storing request content is unavoidable. 9. Add tests confirming that representative passwords, tokens, and personal data never appear in telemetry files.
