Back to skill

Security audit

WorldSim

Security checks across malware telemetry and agentic risk

Overview

This is a coherent local story-simulation skill, but it needs review because some destructive world-data operations are not protected by code-enforced confirmation or verified backups.

Install only if you are comfortable with a skill that writes, rewrites, archives, and deletes local story-world files. Use a dedicated WORLDSIM_WORLDS_DIR, avoid storing secrets or real sensitive personal information in worlds, and make your own backups before using reset, load, delete, or migration operations.

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 (2)

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. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/reset_world.py:48
Finding
World and scene resets continue after automatic backup failure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/reset_world.py:48-61`, `scripts/reset_scene.py:82-90` **Vulnerability Type**: Fail-open destructive operation and unchecked subprocess result **Risk Level**: Medium **Classification**: T09: Insecure Skill Coding Practices ### Vulnerable Code The world-reset path invokes the snapshot process, prints its output, and then deletes dynamic state without checking the subprocess return code: ```python # 安全网:自动存档(可回滚) snapname = f"_before_reset_{datetime.now().strftime('%Y%m%d-%H%M%S')}" p = subprocess.run([sys.executable, str(SCRIPT_DIR / "snap.py"), world, "save", snapname], capture_output=True) print((p.stdout or b"").decode("utf-8", "replace") + (p.stderr or b"").decode("utf-8", "replace"), end="") # 删除动态状态与场景 if (world_dir / "scenes").is_dir(): safe_rmtree(world_dir / "scenes") print(" 删除: scenes/") states_dir = world_dir / "states" if states_dir.is_dir(): for f in sorted(states_dir.iterdir()): if f.is_file(): safe_unlink(f) print(f" 删除: states/{f.name}") ``` The scene-reset path has the same fail-open behavior: ```python # ── 安全网:自动存档(可回滚)── snapname = f"_before_reset_scene_{scene_base}_{datetime.now().strftime('%Y%m%d-%H%M%S')}" p = subprocess.run([sys.executable, str(SCRIPT_DIR / "snap.py"), world, "save", snapname], capture_output=True) print((p.stdout or b"").decode("utf-8", "replace") + (p.stderr or b"").decode("utf-8", "replace"), end="") # ── 1. narrative.md 轮转归档 + 置空 ── narr_file = scene_dir / "narrative.md" ``` After this point, the scene-reset script archives or clears narrative content and rewrites scene and world state even if the snapshot command failed. ### Technical Analysis The reset workflows describe the automatic snapshot as a recoverability safeguard. However, `subprocess.run()` is called without `check=True`, and neither script inspects `p.returncode`. Snapshot creation can fail for several legitimate reasons, including: ...[truncated 2104 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Fail closed when snapshot creation fails: ```python p = subprocess.run( [sys.executable, str(SCRIPT_DIR / "snap.py"), world, "save", snapname], capture_output=True ) if p.returncode != 0: print((p.stdout or b"").decode("utf-8", "replace"), end="") print((p.stderr or b"").decode("utf-8", "replace"), end="", file=sys.stderr) print("[ERR] Reset aborted because the safety snapshot failed.", file=sys.stderr) sys.exit(1) ``` Alternatively, use `check=True` and handle `subprocess.CalledProcessError`. 2. Verify the backup artifact before mutation: - Confirm the expected snapshot directory exists. - Confirm `MANIFEST.md` exists and is readable. - Optionally verify that required state and scene files are represented in the manifest. 3. Perform a disk-space and writability preflight before snapshot creation and reset. 4. Use a transactional reset design: - Stage the reset in a temporary directory. - Atomically rename the current data into a recovery location. - Commit the new state only after all steps succeed. - Restore the previous state automatically if any step fails. 5. Apply identical fail-closed logic to both `reset_world.py` and `reset_scene.py` through a shared helper to prevent implementation drift. 6. Add automated tests that simulate: - Nonzero snapshot subprocess exits. - Permission failures. - Disk exhaustion. - Missing or incomplete manifests. - Successful backup followed by reset failure. - Verification that no destructive mutation occurs after backup failure. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The file is written as a mandatory Chinese-only operational instruction set, and the skill metadata also strongly constrains activation and behavior around that language context. This can cause user-intent mismatch, prevent informed consent or safe review by users/operators who do not read Chinese, and increase the chance that unsafe file-writing or world-state actions occur without the user fully understanding what the agent is doing.

Missing User Warnings

Low
Confidence
94% confidence
Finding
The file explicitly authorizes generating and sending a new scene image to the user when entering a confirmed scene, but the instruction is not paired with a nearby user-facing disclosure or consent reminder. In a skill that persists world state and can act automatically during workflow transitions, this increases the risk of surprising media generation, unintended data exposure through prompts, or bypass of user expectations about when images will be created.

VirusTotal

64/64 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.