Back to skill

Security audit

Huo15 Comic Orchestrator

Security checks for vulnerabilities and agentic risk

Overview

The skill is a media-generation orchestrator with expected external API use, but its billing and dependency controls are too weak for unattended installation.

Install only if you trust the publisher and all required sibling skills, understand that media prompts and referenced assets may be sent to external providers, and can supervise each run. Avoid unattended or auto-confirmed use until dependencies are pinned and runtime spending is enforced from actual provider usage.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:75
Finding

Runtime Cost Cap Is Not Enforced During Billable Subprocess Execution

Content
View full analysis

Vulnerability Details

File Location: scripts/run.py:75-93, 138-154; scripts/_shared/cost_guard.py:46-72
Vulnerability Type: Cost-control enforcement failure
Risk Level: Medium

Vulnerable Code

python
guard = CostGuard.load(project_dir, cap=args.cap)

try:
    guard.preflight(est["total"])
except BudgetExceeded as e:
    print(f"❌ {e}")
    return 2
python
for step, skill, script, sub_args in steps:
    if cp.is_done(step):
        print(f"⏭️  {step}: 已完成,跳过")
        continue
    cp.mark_running(step)
    try:
        run_substep(skill, script, *sub_args)
        cp.mark_done(step)
    except subprocess.CalledProcessError as e:
        cp.mark_failed(step, str(e))
        print(f"❌ {step} 失败: {e}")
        return 3
    except BudgetExceeded as e:
        print(f"🛑 熔断: {e}")
        return 4

report = guard.report()

The runtime enforcement mechanism exists but is never invoked:

python
def charge(self, step: str, item: str, cost: float) -> None:
    self.spent += cost
    self.records.append(CostRecord(step=step, item=item, cost=cost))
    ratio = self.spent / self.cap if self.cap else 0

    if ratio >= 1.0:
        self._persist()
        raise BudgetExceeded(
            f"累计成本 ¥{self.spent:.2f} 达到熔断上限 ¥{self.cap:.2f}({step}/{item})。\n"
            f"已完成步骤可从 checkpoint 续跑。"
        )

Technical Analysis

The orchestrator performs a preflight estimate but never calls CostGuard.charge() after billable image, video, speech, lip-sync, or music operations. As a result, spent remains unchanged in the orchestrator, runtime warnings cannot activate, and the hard cap cannot interrupt subsequent paid operations.

The except BudgetExceeded block around subprocess.run() does not fix this issue. A Python exception raised inside a child process does not propagate into the parent process as the same exception; it is represent ...[truncated 1105 chars]

Remediation
View remediation

Remediation Suggestions

  1. Require every child Skill to return machine-readable actual usage and cost for each billable item.
  2. Call guard.charge(step, item, cost) immediately after each paid request, not merely after the entire child process completes.
  3. Check the remaining budget before submitting each new paid request.
  4. If child processes enforce costs directly, use a shared, atomic, locked cost ledger to prevent races and stale reads.
  5. Define a structured exit status for budget exhaustion and translate it into BudgetExceeded in the parent process.
  6. Include retries and partially completed requests in recorded usage.
  7. Reconcile local records against provider billing or usage responses before presenting the final report.
  8. Add integration tests proving that execution stops before the next billable request once the configured cap is reached.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:49
Finding

Mandatory User Confirmation Can Be Bypassed with a Command-Line Flag

Content
View full analysis

Vulnerability Details

File Location: scripts/run.py:49, 95-97
Vulnerability Type: User authorization gate bypass
Risk Level: Medium

Vulnerable Code

python
p.add_argument("--auto-confirm", action="store_true", help="跳过交互确认")
python
if not args.auto_confirm and not confirm("确认开始? [y/N] "):
    print("已取消。")
    return 0

Technical Analysis

The Skill documentation identifies explicit user confirmation as a mandatory safety rule before paid generation begins. The --auto-confirm option directly bypasses that authorization gate.

This is particularly significant in an Agent-operated context, where command-line arguments may be constructed automatically. The same Agent that proposes a paid action can add the bypass flag and begin execution without receiving the required explicit approval from the user.

The bypass does not require exploitation of parsing or shell behavior; it is an intentionally exposed execution path that conflicts with the declared mandatory control.

Attack Path

  1. An Agent, wrapper, or automation invokes scripts/run.py.
  2. It adds the --auto-confirm option to the command.
  3. The preflight estimate succeeds because it is below the configured cap.
  4. The confirmation condition evaluates to false without reading user input.
  5. Paid sibling Skills begin execution without explicit user approval.

Impact Assessment

This issue does not provide additional system privileges. It allows the caller to bypass the declared user-consent boundary and authorize external API usage on the user’s behalf. The scope includes all generation stages and associated spending initiated by that run.

Remediation
View remediation

Remediation Suggestions

  1. Remove --auto-confirm from user-facing execution paths.
  2. If noninteractive operation is necessary, define a separately documented trusted automation mode.
  3. Require that automation mode to present a signed or otherwise independently authorized approval containing the project parameters and immutable budget.
  4. Ensure the approved theme, duration, provider options, and cost cap cannot change after authorization.
  5. Record the confirmation source, approved estimate, timestamp, and effective arguments in an audit log.
  6. Add tests verifying that ordinary Agent invocations cannot begin paid work without affirmative user input.

T07 · Tool Hijacking and Spoofing

Warning
Location
scripts/run.py:15
Finding

Unauthenticated Sibling Skill Scripts Are Executed with Inherited Privileges

Content
View full analysis

Vulnerability Details

File Location: scripts/run.py:15-16, 54-63, 101-135
Vulnerability Type: Local tool substitution and execution
Risk Level: Medium

Vulnerable Code

python
HERE = pathlib.Path(__file__).resolve()
REPO_ROOT = HERE.parents[2]
python
def run_substep(skill_name: str, script: str, *args: str) -> subprocess.CompletedProcess:
    """调用子 skill 的脚本."""
    cmd = [
        sys.executable,
        str(REPO_ROOT / skill_name / "scripts" / script),
        *args,
    ]
    print(f"  $ {' '.join(cmd)}")
    return subprocess.run(cmd, check=True)

Representative sibling dependencies are selected by directory and filename:

python
steps = [
    ("script",      "huo15-comic-script",      "script_gen.py",
        ["--theme", args.theme, "--duration", str(args.duration),
         "--style", args.style, "--genre", args.genre,
         "--out", str(project_dir / "script.json")]),
    ("characters",  "huo15-comic-character",   "character.py",
        ["--script", str(project_dir / "script.json"),
         "--out-dir", str(project_dir / "characters")]),
    ("storyboard",  "huo15-comic-storyboard",  "storyboard.py",
        ["--script", str(project_dir / "script.json"),
         "--char-dir", str(project_dir / "characters"),
         "--out-dir", str(project_dir / "storyboard")]),
    ("videos",      "huo15-comic-video",       "video.py",
        ["--script", str(project_dir / "script.json"),
         "--frame-dir", str(project_dir / "storyboard"),
         "--out-dir", str(project_dir / "videos")]),
    ("dubs",        "huo15-comic-dub",         "dub.py",
        ["--script", str(project_dir / "script.json"),
         "--out-dir", str(project_dir / "audio")]),
]

Technical Analysis

The orchestrator resolves executable dependencies from sibling directories under REPO_ROOT and runs them without checking a version, digest, signatur ...[truncated 1730 chars]

Remediation
View remediation

Remediation Suggestions

  1. Package reviewed child implementations with the orchestrator or pin each sibling dependency to a specific trusted version.
  2. Maintain a signed manifest of allowed script paths and cryptographic hashes.
  3. Verify each dependency’s signature or digest before execution and fail closed on mismatch.
  4. Resolve dependencies from a trusted, read-only installation directory rather than a generally writable shared parent.
  5. Reject symbolic links and verify the final resolved path remains inside the approved installation root.
  6. Launch children with a minimal explicit environment instead of inheriting all parent variables.
  7. Provide only the specific credential required by each child and use narrowly scoped provider credentials where supported.
  8. Audit all eight sibling Skills before treating the end-to-end workflow as trusted.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明描述的是一个端到端的漫剧制作工作流,包含多阶段内容生成、音视频后处理、成本控制和容错恢复等完整能力。但给出的代码片段只是底层 API 客户端与少量辅助函数:调用图像生成、视频生成、TTS、视频下载,并计算视频 token 成本。它没有展示剧本、角色卡、字幕、BGM、口型同步、成片拼接等核心业务流程,也没有实现所宣称的三级成本熔断和失败续跑。因此,代码行为与技能声明存在明显的能力范围不匹配。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises and instructs use of shell execution, file read/write, environment access, and likely networked sub-skills, but declares no explicit tool scope or permissions boundary. In an agent setting, this creates over-broad ambient authority: a caller or downstream workflow could trigger filesystem changes, command execution, or credential-bearing network activity without a documented least-privilege contract.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Broad trigger phrases like common-language requests for making a comic drama increase the chance of accidental or overly eager invocation. Because this skill can lead to shell execution, file writes, and multi-step media generation with cost implications, unintended activation is more dangerous here than in a read-only or low-impact skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/_shared/ark_api.py (reported line 66)May include surrounding context.

python
"size": size,
            "watermark": False,
        }
        resp = requests.post(
            f"{self.base_url}/images/generations",
            headers=self.headers,
            json=body,

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

The video submission method can transmit local file contents and caller-supplied remote URLs/reference media to an external provider without any validation or trust-boundary enforcement. In this skill context, inputs may be derived from prior workflow stages or user-provided assets, so accidental exfiltration of sensitive local media or internal-only URLs is plausible if untrusted paths/URLs are passed through.

Content

Scanner excerpt · scripts/_shared/ark_api.py (reported line 144)May include surrounding context.

python
if seed is not None:
            body["seed"] = seed

        resp = requests.post(
            f"{self.base_url}/contents/generations/tasks",
            headers=self.headers,
            json=body,

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/_shared/ark_api.py (reported line 207)May include surrounding context.

python
if emotion:
            body["emotion"] = emotion

        resp = requests.post(
            f"{self.base_url}/audio/speech",
            headers=self.headers,
            json=body,

Tainted flow: 'resp' from requests.get (line 158, network input) → pathlib.Path.write_bytes (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/_shared/ark_api.py (reported line 216)May include surrounding context.

python
resp.raise_for_status()
        out = pathlib.Path(out_path)
        out.parent.mkdir(parents=True, exist_ok=True)
        out.write_bytes(resp.content)
        return out

    # ------------ 工具 ------------

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/_shared/config.py (reported line 35)May include surrounding context.

python
# API 端点(2026-04 核对)
ENDPOINTS = {
    "ark_base":      "https://ark.cn-beijing.volces.com/api/v3",
    "kling_base":    "https://api.klingai.com/v1",         # 官方;第三方 piapi.ai/fal.ai 亦可
    "suno_base":     "https://api.sunoapi.org",             # 第三方(Suno 无公开官方 API)
}

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This file contains user-facing natural-language content such as docstrings, warnings, and exception messages entirely in Chinese. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains natural-language instructions and usage text only in Chinese, including the main docstring and CLI help context. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/run.py (reported line 44)May include surrounding context.

python
p.add_argument("--no-lipsync", action="store_true")
    p.add_argument("--no-bgm", action="store_true")
    p.add_argument("--output-root", default=str(REPO_ROOT / "output"))
    p.add_argument("--auto-confirm", action="store_true", help="跳过交互确认")
    return p.parse_args()

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 56)May include surrounding context.

python
*args,
    ]
    print(f"  $ {' '.join(cmd)}")
    return subprocess.run(cmd, check=True)


def confirm(prompt: str) -> bool:

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/run.py (reported line 98)May include surrounding context.

python
print(f"❌ {e}")
        return 2

    if not args.auto_confirm and not confirm("确认开始? [y/N] "):
        print("已取消。")
        return 0

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The rule "国风为默认" establishes a default stylistic and cultural locale preference, but the document does not clearly present this as an opt-in regional specialization or offer an explicit user choice at activation. Under the policy, forced or implicit locale defaults can be problematic unless clearly justified or optional.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The TTS method defaults to a Chinese voice ID (zh_female_sinong_conversation_wvae_bigtts), which imposes a specific language/locale choice unless callers explicitly override it. The file does not indicate user opt-in or that the skill is intentionally limited to a Chinese-language context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code file contains a Chinese-only module docstring, which can be read as enforcing a specific language for documentation without any user opt-in or alternative locale. The policy explicitly asks to flag language or locale constraints that force a specific language absent a documented choice or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The method docstring is written only in Chinese and does not indicate that this locale restriction is optional, user-selectable, or specifically justified. Under the stated policy, natural-language content that forces a specific language can be a violation across any file type.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The module-level docstring, comments, style presets, genre presets, and voice preset identifiers are all written specifically for Chinese-language and Chinese-culture outputs, with no indication that users may choose another language or locale. Under the policy, a skill that imposes a specific language/locale without user opt-in can be a natural-language policy violation unless the constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.