T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/worldctl.py:2997
- Finding
- Destructive YAML deletion bypasses mandatory user confirmation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/worldctl.py:2865-2870`, `scripts/worldctl.py:2997-3058` **Vulnerability Type**: Missing authorization and confirmation check for destructive operations **Risk Level**: Medium **Classification**: T09: Insecure Skill Coding Practices ### Vulnerable Code Direct and batch deletion both reach `cmd_delete()` without requiring confirmation: ```python for idx, (kind, file_key, key_path_str, content, append) in enumerate(ops): if idx in blocked: continue if kind == "delete": cmd_delete(world_dir, [file_key, key_path_str]) continue ``` The deletion function immediately removes the selected key and writes the modified YAML document: ```python def cmd_delete(world_dir: Path, extra: list[str]): """ delete: 删除指定键路径。 用法: worldctl.py <世界> delete <文件key> <YAML键路径> 示例: worldctl.py westworld delete conflicts CT-05 ← 删除整条 CT worldctl.py westworld delete pending_actions 已完成.PA-002 """ if len(extra) < 2: print("[ERR] 用法: worldctl.py <世界> delete <文件key> <YAML键路径>", file=sys.stderr) sys.exit(1) file_key = extra[0] key_path_str = extra[1] scene_dir = get_scene_dir(world_dir) existing = discover_files(world_dir, scene_dir) filepath, note = resolve_char_file(existing, file_key, world_dir) if filepath is None: if note: print(note, file=sys.stderr) else: print(f"[ERR] 未知文件 key: {file_key}", file=sys.stderr) return if note: print(note, file=sys.stderr) if filepath.name == "world_map.yaml": print("[ERR] world_map 禁用点路径删除(键名可含空格/点·点路径与 shell 分词均不支持)——请用 write 命令(YAML diff 合并)", file=sys.stderr) return if not filepath.exists(): print(f"[WARN] {file_key} 文件不存在,无需删除", file=sys.stderr) return try: data = yaml.safe_load(filepath.read_text(encoding="utf-8")) or {} except Exception as e: print( ...[truncated 2965 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Enforce confirmation inside the destructive function rather than relying on Agent instructions: - Add a `force` or validated confirmation-token parameter to `cmd_delete()`. - Refuse non-interactive deletion unless explicit authorization is supplied. - Prompt with a default-deny `[y/N]` confirmation in interactive use. 2. Apply the same authorization requirement to batch `###DELETE:` operations: - Reject batches containing deletion unless a dedicated destructive-operation flag is present. - Prefer a narrowly scoped confirmation token bound to the world, file key, and YAML path. - Do not let the general write or rollback force option implicitly authorize unrelated deletion. 3. Create a recoverable snapshot before applying deletion, and abort if snapshot creation fails. 4. Make `cmd_delete()` return an explicit success or failure result. The batch executor should treat a failed deletion as a failed operation rather than continuing silently. 5. Log the exact world, file, key path, confirmation source, and snapshot identifier for every destructive operation. 6. Add tests covering: - Direct deletion without confirmation. - Batch deletion without confirmation. - Non-interactive execution. - Declined confirmation. - Snapshot failure. - Authorized deletion of a valid key. ]]>
