T01 · Skill Instruction Hijacking
Warning
- Location
- scripts/openclaw_cron_builder.py:49
- Finding
- Stored Prompt Injection in Scheduled Agent Messages## Vulnerability Details **File Location**: `scripts/config_manager.py:363,399`; `scripts/openclaw_cron_builder.py:49-64,100-106` **Vulnerability Type**: Stored prompt injection through an untrusted search keyword **Risk Level**: Medium ### Vulnerable Code `scripts/config_manager.py:363` accepts the keyword as unrestricted text: ```python parser.add_argument("--keyword", "-k", type=str, help="搜索关键词") ``` `scripts/config_manager.py:397-404` persists the value: ```python if args.save: config = save_config( keyword=args.keyword, max_results=args.max, sort=args.sort, timezone=args.timezone, ) ``` `scripts/openclaw_cron_builder.py:49-64` directly interpolates that value into an agent instruction: ```python def build_analysis_message(config: Dict[str, Any]) -> str: keyword = config.get("keyword") max_results = config.get("max_results") sort = config.get("sort") timezone = config.get("timezone") or DEFAULT_TIMEZONE if not keyword: raise ValueError("当前配置缺少 keyword,无法构造任务消息") return ( "请使用当前技能的已保存配置执行一次完整 arXiv 监控流程。" f"检索关键词是 {keyword}。" f"返回数量是 {max_results}。" f"排序方式是 {sort}。" f"时区按 {timezone} 处理。" "请先搜索最新论文,再基于标题和摘要逐篇分析,最后输出完整结构化报告。" "报告必须包含论文列表、每篇论文的关注热点、创新性评估、热点研究方向 Top 10,以及 3 到 5 条趋势判断。" ) ``` `scripts/openclaw_cron_builder.py:100-106` places the generated string in an `agentTurn` payload: ```python payload: Dict[str, Any] = { "name": job_name or derive_job_name(config["keyword"]), "schedule": schedule, "sessionTarget": session_target, "payload": { "kind": "agentTurn", "message": build_analysis_message(config), }, } ``` ### Technical Analysis The search keyword is treated both as data and as part of the natural-language instruction sent to a future agent invocation. No allowlist, escapi ...[truncated 1787 chars]
- Remediation
- ## Remediation Suggestions 1. Pass the search query as a typed data field separate from the agent's instruction text whenever the OpenClaw payload format permits it. 2. If a text-only payload is required, serialize the keyword using a defined encoding such as JSON and place it inside an explicit untrusted-data boundary. 3. Add an instruction stating that content inside the query field is data only and must never be interpreted as an instruction. This should supplement, not replace, structural separation. 4. Validate keywords against the intended arXiv query grammar and reject control characters, excessive lengths, and unsupported syntax. 5. Require explicit review or confirmation of the final generated agent message before creating a recurring task. 6. Restrict permissions on `config.json` so untrusted local users or processes cannot replace the stored query. 7. Add tests using instruction-like keywords to verify that they remain inert search data.
