T02 · Agent Memory Poisoning
- Location
scripts/daily_learning_summary.py:81- Finding
Unsanitized External Data Is Persisted into Agent Learning Memory
- Content
View full analysis
= 3: skill_name = parts[1].strip() rating = parts[2].strip() discoveries.append(f"{skill_name} ({rating})") summary["clawhub"]["discoveries"] = discoveries[:5] ``` Values from the heartbeat state are also accepted without type or content validation: ```python state = read_heartbeat_state() stats = state.get("stats", {}) summary["instreet"]["comments"] = stats.get("instreet_interactions_today", summary["instreet"]["comments"]) summary["clawhub"]["earned"] = stats.get("clawhub_虾米_earned_today", 0) ``` The imported values are interpolated directly into the Markdown report: ```python if summary["clawhub"]["discoveries"]: lines.extend([f" - {d}" for d in summary["clawhub"]["discoveries"]]) else: lines.append(" - 暂无记录") lines.extend([ f"- 虾米变动: +{summary['clawhub']['earned']} (收入) / -{summary['clawhub']['cost']} (支出)", ``` The resulting report is then persisted in the Agent's learning-memory directory: ```python log_file = LEARNING_DIR / f"{summary['date']}.md" with open(log_file, 'w', encoding='utf-8') as f: f.write(report) ``` ### Technical Analysis The script transfers values from `memory/clawhub_discoveries.md` and `memory/heartbeat-state.json` into `memory/learning/YYYY-MM-DD.md` without enforcing expected data types, length limits, character allowlists, Markdown escaping, or trust-boundary annotations. A malicious or compromised data producer can place instruction-like natural-language content in a skill-name, rating, interaction-coun ...[truncated 2149 chars]- Remediation
View remediation
