Back to skill

Security audit

Agent Avengers

Security checks for vulnerabilities and agentic risk

Overview

This multi-agent orchestration skill is not clearly malicious, but it needs Review because it delegates work broadly and has unsafe command/path handling plus retained sessions that are not clearly disclosed.

Install only after reviewing the generated execution commands and understanding that task details may be sent to multiple agents or profiles. Avoid using sensitive data unless you have confirmed where spawned sessions, mission files, logs, and reports are stored and how to delete them. Run the scripts with least privilege and treat subtasks JSON, mission IDs, and execution_plan.json as trusted inputs only.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/execute.py:73
Finding

OpenClaw Command Injection Through Unescaped Execution-Plan Content

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/execute.py:19
Finding

Mission Path Traversal and Untrusted Mission-Path Redirection

Content
View full analysis
tuple: """미션 및 실행 계획 로드""" mission_path = MISSION_DIR / mission_id with open(mission_path / "mission.json") as f: mission = json.load(f) with open(mission_path / "execution_plan.json") as f: plan = json.load(f) return mission, plan ``` The path loaded from the mission file is then trusted: ```python mission_path = Path(mission["path"]) ``` The same pattern appears in `scripts/consolidate.py`: ```python def load_mission(mission_id: str) -> tuple: """미션 및 실행 계획 로드""" mission_path = MISSION_DIR / mission_id with open(mission_path / "mission.json") as f: mission = json.load(f) with open(mission_path / "execution_plan.json") as f: plan = json.load(f) return mission, plan ``` ```python mission_path = Path(mission["path"]) ``` ### Technical Analysis The value supplied through `--mission` is appended to `MISSION_DIR` without validation or canonical containment checks. A mission value containing `..` components can escape the intended mission directory. In Python’s `pathlib`, an absolute right-hand operand can also replace the base path entirely. After loading `mission.json`, the scripts trust the serialized `path` field instead of deriving a canonical path from the validated mission identifier. This creates a second redirection opportunity: a crafted mission file can direct subsequent log, output, status, and report operations to another filesystem location. No `resolve()` and containment comparison is performed at either stage. ### Attack Path 1. An attacker obtains the ability to invoke ...[truncated 1532 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/consolidate.py:31
Finding

Agent Output Path Traversal Through Unvalidated Plan Identifiers

Content
View full analysis
list: """에이전트 출력 수집""" outputs_dir = mission_path / "outputs" results = [] for cmd in plan.get("commands", []): agent_id = cmd["agent_id"] output_file = outputs_dir / f"{agent_id}.md" if output_file.exists(): with open(output_file) as f: content = f.read() results.append({ "agent_id": agent_id, "status": "completed", "content": content, "file": str(output_file), "size": len(content) }) ``` The equivalent monitor logic is: ```python for cmd in plan.get("commands", []): agent_id = cmd["agent_id"] output_file = outputs_dir / f"{agent_id}.md" status = "pending" output_size = 0 if output_file.exists(): status = "completed" output_size = output_file.stat().st_size ``` ### Technical Analysis The `agent_id` value is loaded from the mutable `execution_plan.json` file and used directly as part of an output filename. The implementation does not reject path separators, traversal components, absolute paths, or unexpected identifier syntax. Plans normally generated by `assemble.py` use timestamp-derived identifiers. However, the consuming functions do not enforce that invariant and treat the plan as trusted. A modified or independently crafted plan can therefore contain an identifier with traversal segments. Because the `.md` suffix is appended after the untrusted value, exploitation is generally limited to files whose resulting path ends in `.md`. This still permits reading Markdown file ...[truncated 1249 chars]
Remediation
View remediation

other

Note
Location
scripts/assemble.py:156
Finding

Spawned Agent Sessions Are Retained Contrary to the Advertised Cleanup Policy

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

설명은 엔드투엔드 멀티에이전트 오케스트레이션을 약속하지만, 제공된 코드 조각은 주로 '계획 수립기' 역할이다. decompose_task는 빈 리스트를 반환하며 자동 분해가 구현되지 않았고, --task만 주어지면 분해가 필요하다고 안내만 한다. 또한 sessions_spawn/sessions_send를 실제 호출하지 않고 해당 호출용 파라미터를 execution_plan.json에 기록할 뿐이어서 에이전트를 즉석 생성하거나 병렬 실행하지 않는다. 의존성 기반 phase 계산은 병렬 가능성을 표시하지만 실제 실행 엔진은 없다. 마지막으로 결과를 수집·통합하는 로직도 없다. 따라서 선언된 핵심 기능 대비 실제 동작이 materially 부족하여 설명-행동 불일치로 판단된다.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

설명은 멀티에이전트 시스템 전체를 자동 오케스트레이션하는 핵심 기능(태스크 분해, 에이전트 생성, 병렬 처리, 통합)을 약속한다. 그러나 이 코드 조각은 이미 존재하는 execution_plan과 에이전트 출력 파일을 기반으로 결과를 읽고 누락 여부를 검사하며 FINAL_REPORT.md를 작성하는 'consolidation' 단계만 수행한다. mission.json 수정과 파일 입출력은 선언된 통합 목적과 관련된 범위 내이지만, 설명의 주된 가치 제안인 자동 멀티에이전트 구성/실행 기능을 구현하지 않는다. 따라서 코드의 실제 1차 목적은 설명보다 훨씬 좁고 materially different 하므로 mismatch로 판단한다.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

설명은 이 스킬의 핵심 기능이 멀티에이전트 오케스트레이션 전체 흐름(분해, 생성, 실행, 통합)이라고 주장한다. 그러나 실제 코드 조각은 저장된 미션 메타데이터와 출력 파일 존재 여부를 확인해 진행률을 계산하고 로그를 출력하는 읽기 중심의 모니터링 도구다. 일부 문자열에 consolidate.py 안내가 나오지만 직접 통합을 실행하지 않으며, 에이전트를 만들거나 태스크를 분해하거나 병렬 작업을 관리하는 로직도 없다. 따라서 선언된 주된 목적과 실제 동작 사이에 중대한 불일치가 있다.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Yes, this is a mismatch. The declared description claims substantial multi-agent automation capabilities, but the supplied code chunk is only an empty test-package initializer with a comment. There is no functional code supporting the stated purpose. While this may be only a partial repository snippet, based on the supplied code alone the actual behavior does not match the declared functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

설명은 복잡한 태스크를 자동 분해하고 여러 전문 에이전트를 동적으로 생성하여 병렬 실행·통합하는 '오케스트레이션' 시스템을 주장한다. 그러나 제공된 코드 조각은 scripts/consolidate의 함수들에 대한 테스트 파일로, 이미 존재하는 출력 파일을 읽고, 누락/빈 결과를 검증하며, 텍스트 요약을 생성하는 동작만 확인한다. 즉 일부 '결과 통합' 측면은 간접적으로 관련이 있지만, 핵심으로 선언된 에이전트 생성, 태스크 분해, 병렬 오케스트레이션, 트리거 기반 실행 같은 주된 기능은 나타나지 않는다. 따라서 선언된 목적과 실제 코드의 주된 역할 사이에 중대한 불일치가 있다.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · scripts/monitor.py (reported line 147)May include surrounding context.

python
try:
        while True:
            os.system('clear' if os.name == 'posix' else 'cls')
            
            mission, plan = load_mission(mission_id)
            mission_path = Path(mission["path"])

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description highlights autonomous decomposition, team formation, parallel execution, and result consolidation but does not warn users that their task contents may be redistributed across multiple agents or profiles. In this context, the omission increases the chance that sensitive inputs are shared more widely than the user realizes, especially because the skill explicitly supports temporary agents and other bot instances.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The example invocation uses a very broad natural-language trigger ("어벤저스 어셈블!") without stating activation boundaries, consent requirements, or exclusions. In a skill that orchestrates automatic task decomposition and multi-agent execution, ambiguous triggering can cause unintended activation on ordinary user phrasing, leading to unnecessary delegation, unintended data propagation to subagents, or autonomous report generation beyond user expectations.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents code-capable operations such as sessions spawning, inter-agent messaging, profile routing, shared memory, and file-writing behavior, but it does not declare any explicit tool scope or allowed-tools boundary. In an orchestration skill that can delegate work and potentially touch shell, environment, and files, missing permission constraints significantly increases the risk of overbroad execution, unintended delegation, and privilege misuse.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The natural-language instructions, examples, and usage guidance are presented entirely in Korean, but the document does not state that this is a Korea-specific skill or offer users a language option. Under the language/locale policy, forcing a specific language without opt-in can be a policy concern.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger list includes broad natural-language phrases such as '멀티에이전트 자동화', '에이전트 팀 구성', and '자동 에이전트' that could match ordinary user requests and activate a high-impact orchestration skill unexpectedly. In this context, accidental activation is more dangerous because the skill is designed to delegate tasks, spawn agents, and potentially use powerful tools across profiles.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This JSON manifest uses Korean for the task and all subtask descriptions/expected outputs, which effectively constrains the skill to a specific language/locale. The file does not indicate any user opt-in, language selection, or region-specific justification, so it conflicts with the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrase set includes broad, generic terms such as "에이전트 팀" and collaboration-oriented wording that could match ordinary user requests unrelated to this specific skill. In an orchestration skill that can automatically decompose tasks and spawn multiple agents, accidental invocation increases the chance of unexpected automation, excessive tool use, or unintended delegation of sensitive work.

Content

No source excerpt is available for this finding.

Tainted flow: 'mission_path' from os.environ.get (line 194, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/assemble.py (reported line 81)May include surrounding context.

python
}
    
    # 미션 파일 저장
    with open(mission_path / "mission.json", "w") as f:
        json.dump(mission, f, indent=2, ensure_ascii=False)
    
    return mission

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes an all-in-one system that automatically breaks down complex tasks and dynamically creates/spawns specialist agents. In code, decompose_task is a stub that always returns an empty list, and the script only emits JSON command parameters for later execution rather than performing the orchestration it advertises.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The spawned agent prompt is written entirely in Korean and instructs the agent in that language, which can force a specific language/locale on downstream behavior. The file does not provide any user opt-in, fallback, or explanation that the skill is intentionally Korean-only.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The message sent to existing agents is always composed in Korean, which imposes a language choice without opt-in. This matches the language/locale policy concern because no alternative locale handling or explicit justification is present.

Content

No source excerpt is available for this finding.

Tainted flow: 'mission_path' from os.environ.get (line 194, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/assemble.py (reported line 256)May include surrounding context.

python
})
    
    # 계획 저장
    with open(mission_path / "execution_plan.json", "w") as f:
        json.dump(plan, f, indent=2, ensure_ascii=False)
    
    return str(mission_path / "execution_plan.json")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module description and later user-facing strings are written in Korean, indicating the skill is designed to communicate in a specific language. The file does not offer any opt-in or alternative locale handling, which matches the policy category for language/locale constraints in natural-language content.

Content

No source excerpt is available for this finding.

Tainted flow: 'mission_path' from os.environ.get (line 20, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
90% confidence
Finding

The script ultimately writes to mission.json under a mission_path derived from mission metadata loaded from a workspace rooted in an environment-controlled base directory and a user-supplied mission ID. Because mission["path"] is trusted without canonicalization or containment checks, an attacker who can influence the workspace contents or mission metadata can redirect writes to arbitrary filesystem locations, causing unauthorized file overwrite. In a multi-agent orchestration skill that reads and writes many files automatically, this trust boundary issue is more dangerous because untrusted agent-produced state may be fed back into privileged file operations.

Content

Scanner excerpt · scripts/consolidate.py (reported line 151)May include surrounding context.

python
if updates:
        mission.update(updates)
    
    with open(mission_path / "mission.json", "w") as f:
        json.dump(mission, f, indent=2, ensure_ascii=False)

Tainted flow: 'output_path' from os.environ.get (line 196, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
95% confidence
Finding

The report output path is attacker-controllable through the --output argument, and the default path also depends on untrusted mission_path state. The script opens that path for writing without validation, enabling arbitrary file overwrite or clobbering if a caller supplies a sensitive path or if mission metadata points outside the intended workspace. In an automation skill intended to consolidate outputs, this is especially risky because operators may run it with elevated privileges over broad workspaces.

Content

Scanner excerpt · scripts/consolidate.py (reported line 198)May include surrounding context.

python
else:
        output_path = mission_path / "FINAL_REPORT.md"
    
    with open(output_path, "w") as f:
        f.write(report)
    
    # 상태 업데이트

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring says the script performs agent spawn/dispatch execution based on the execution plan, and the CLI description also presents it as an execute command. In practice, the code generates OpenClaw command strings, logs the mission as started/executing, prints them for a human to run, and never actually invokes any agent-spawning API itself.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code file contains natural-language strings that present the skill in Korean, starting with the module description at L004 and continuing in user-facing CLI help/output. The policy allows locale constraints only when the skill offers language choice or clearly documents and justifies the restriction, which is not present here.

Content

No source excerpt is available for this finding.

Tainted flow: 'mission_path' from os.environ.get (line 21, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
88% confidence
Finding

The write target is ultimately derived from mission metadata loaded from a mission directory whose root comes from an environment-controlled workspace and user-supplied mission ID. Because mission_path is taken from mission["path"] without validation, a crafted mission file can redirect writes to arbitrary filesystem locations, causing file overwrite or corruption under the current user's privileges.

Content

Scanner excerpt · scripts/execute.py (reported line 43)May include surrounding context.

python
if updates:
        mission.update(updates)
    
    with open(mission_path / "mission.json", "w") as f:
        json.dump(mission, f, indent=2, ensure_ascii=False)

Tainted flow: 'log_file' from os.environ.get (line 49, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
87% confidence
Finding

The log file path is built from mission_path, which is attacker-influenced through environment/workspace selection and untrusted mission metadata. An attacker who can plant or modify mission.json can cause append operations to arbitrary files, enabling log injection, file clobbering, or pollution of sensitive user files.

Content

Scanner excerpt · scripts/execute.py (reported line 57)May include surrounding context.

python
"data": data or {}
    }
    
    with open(log_file, "a") as f:
        f.write(json.dumps(entry, ensure_ascii=False) + "\n")

Static analysis

No suspicious patterns detected.