Back to skill

Security audit

Sauce Duck Video Maker

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed RunningHub video generator, but it handles the user's API key in ways that can expose it to logs, local config, command arguments, and even an arbitrary configured host.

Review before installing. Use only a low-privilege RunningHub API key, confirm the host is exactly www.runninghub.cn or www.runninghub.ai, and rotate the key if it has already been used with this skill in an environment where command logs, transcripts, or ~/.openclaw/openclaw.json may be accessible.

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

Error
Location
scripts/create_task.py:13
Finding

API Key Exfiltration Through an Unvalidated Network Destination

Content
View full analysis
dict: """创建酱板鸭视频生成任务""" url = f"https://{host}/task/openapi/create" headers = { "Host": host, "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } data = { "apiKey": api_key, "workflowId": "2037239092089458690", "nodeInfoList": [ { "nodeId": "385", "fieldName": "value", "fieldValue": language } ] } req = urllib.request.Request( url, data=json.dumps(data).encode("utf-8"), headers=headers, method="POST" ) with urllib.request.urlopen(req, timeout=30) as response: return json.loads(response.read().decode("utf-8")) ``` `scripts/config_host.py:57-73, 88-90`: ```python def set_host(host): """设置sauce-duck-videos.env.RH_HOST""" config = load_config() or {} if "skills" not in config: config["skills"] = {} if "entries" not in config["skills"]: config["skills"]["entries"] = {} skill_config = config["skills"]["entries"].get("sauce-duck-videos", {}) skill_config["enabled"] = True if "env" not in skill_config: skill_config["env"] = {} skill_config["env"]["RH_HOST"] = host config["skills"]["entries"]["sauce-duck-videos"] = skill_config save_config(config) ``` ```python elif sys.argv[1] == "--set" and len(sys.argv) >= 3: host = sys.argv[2] set_host(host) ``` `scripts/query_task.py:13-33`: ```python def query_task(host: str, api_key: str, task_id: str) -> dict: """ ...[truncated 3575 chars]
Remediation
View remediation
str: normalized = host.strip().lower().rstrip(".") if normalized not in ALLOWED_HOSTS: raise ValueError("Unsupported RunningHub host") return normalized ``` 2. Do not use suffix-based checks such as `host.endswith("runninghub.ai")`, because values such as `evilrunninghub.ai` can bypass them. 3. Reject values containing URL schemes, user information, paths, query strings, fragments, or unauthorized ports. Prefer selecting a predefined base URL from an internal mapping rather than constructing it from free-form input: ```python BASE_URLS = { "cn": "https://www.runninghub.cn", "global": "https://www.runninghub.ai", } ``` 4. Validate the destination again immediately before every credential-bearing request. This prevents direct invocation of the request scripts from bypassing configuration-time checks. 5. Verify whether RunningHub requires `apiKey` in the request body. If bearer authentication is sufficient, remove the duplicate body field to minimize credential exposure. 6. Add tests that reject attacker-controlled hosts, subdomain tricks, trailing-dot variants, embedded credentials, custom ports, and path-bearing input. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get_env.py:16
Finding

API Key Exposure Through Process Arguments, Tool Output, and Plaintext Configuration

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented operations do not implement multilingual content creation or meme composition directly; instead they query and poll remote tasks using host, API key, and task ID. In context, that makes the misleading description more dangerous because it disguises a credentialed network client as a simple media tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented operations do not implement multilingual content creation or meme composition directly; instead they query and poll remote tasks using host, API key, and task ID. In context, that makes the misleading description more dangerous because it disguises a credentialed network client as a simple media tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented operations do not implement multilingual content creation or meme composition directly; instead they query and poll remote tasks using host, API key, and task ID. In context, that makes the misleading description more dangerous because it disguises a credentialed network client as a simple media tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented operations do not implement multilingual content creation or meme composition directly; instead they query and poll remote tasks using host, API key, and task ID. In context, that makes the misleading description more dangerous because it disguises a credentialed network client as a simple media tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented operations do not implement multilingual content creation or meme composition directly; instead they query and poll remote tasks using host, API key, and task ID. In context, that makes the misleading description more dangerous because it disguises a credentialed network client as a simple media tool.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares executable behavior that reads and writes local configuration and performs network/API operations, but it does not declare a corresponding tool scope such as permissions or allowed-tools. This weakens least-privilege controls and makes it harder for reviewers and users to understand the real capabilities of the skill before activation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger description is broad enough to overlap with generic video-creation requests, increasing the chance the skill will be invoked outside the narrow context users intend. When combined with credential handling and local config writes, overbroad invocation raises the risk of surprising sensitive actions during ordinary media requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to collect and persist an API key but provides no warning about where the credential is stored, who can access it, or the risks of reuse and exfiltration. In a skill that also reads/writes local config and performs network calls, the absence of credential-safety disclosure meaningfully increases the chance of unsafe secret handling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The --check path prints the stored apiKey directly to stdout, which can expose the secret in terminal history, logs, CI output, or to any caller invoking the script programmatically. In a skill configuration utility, this is unnecessary for normal health checks and increases the chance of credential leakage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script accepts the API key as a positional command-line argument and also includes it in the JSON request body, which can expose the credential through shell history, process listings, CI logs, or wrapper tooling. Although the request uses HTTPS, the handling pattern increases the chance of accidental credential disclosure, especially in agent or automation environments where arguments and stdout/stderr are commonly recorded.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script reads a globally stored OpenClaw skill API key from the user's home-directory configuration and makes it available to the skill, which exceeds the minimum access implied by a simple video-generation helper. Accessing credentials from a broader shared config increases the blast radius if the skill is compromised or behaves unexpectedly, because it can retrieve sensitive data unrelated to the immediate user action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script prints the retrieved API key as JSON to stdout, which can expose the credential to logs, calling processes, other tools, or downstream prompts without any warning to the user. In a skill context, stdout is often consumed by orchestration layers, making secret disclosure much more dangerous than a local-only read.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script requires the API key as a command-line argument, which can expose the secret through shell history, process listings, job control logs, CI logs, or audit tooling on multi-user systems. While this is a common convenience pattern in scripts, it creates unnecessary credential disclosure risk if the environment is shared or command invocations are logged.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module docstring and success message are written only in Chinese, which imposes a specific language on users without any opt-in or alternative. This matches the policy category for language or locale constraints expressed in natural-language content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring and user-facing usage/help text are written in Chinese, and the success message later is also fixed in Chinese. For a general-purpose configuration script, this imposes a specific language/locale without any opt-in or alternative, which matches the language-policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Natural-language strings in the module docstring and function docstring are written only in Chinese, and the script provides no indication that users may choose another interface language. That can conflict with language/locale policy expectations when a skill imposes a specific language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring and later user-visible messages are written only in Chinese, which imposes a specific language on users without opt-in or an alternative locale. The policy explicitly calls for flagging language or locale constraints when they are forced rather than user-selectable or clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The function docstring and runtime error/output strings such as the unknown-status and timeout messages are presented only in Chinese. This continues the same language-policy issue by forcing one locale in operational output with no user choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.