Back to skill

Security audit

WayinVideo - Video Understanding & AI Clipping

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a real WayinVideo integration, but it asks the agent to act before consent and uses broad upload, credential, download, and persistence behavior that needs human review before install.

Install only if you are comfortable sending selected videos and URLs to WayinVideo with your WAYIN_API_KEY. Before use, require explicit confirmation before any local file upload, paid/API job, export download, background polling, or global config change. Prefer --no-save or a private project directory for sensitive videos, and do not use the documented curl template with untrusted filenames or links without safer argument handling.

Vulnerability Patterns
  • 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
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (6)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:99
Finding

Skill Instructions Suppress Consent Before External Actions

Content
View full analysis
` without separately confirming ...[truncated 720 chars]
Remediation
View remediation

T02 · Agent Memory Poisoning

Warning
Location
SKILL.md:73
Finding

Inferred User Preferences Are Persisted Globally Without Explicit Opt-In

Content
View full analysis
` to save these preferences globally, ensuring a smoother and more personalized experience. Examples: - `wayinvideo config set defaults.target zh` - `wayinvideo config set defaults.clip.ratio RATIO_9_16` ``` ### Technical Analysis The instructions tell the Agent to infer preferences from prior interactions and write them into global persistent configuration. These settings survive the current task and alter later submissions. The configuration values affect generated content, target language, subtitle behavior, aspect ratio, rendering, and other processing defaults. Inference from conversational patterns is not equivalent to explicit authorization to create persistent state. Although this is ordinary application configuration rather than a startup backdoor, it creates a cross-session behavioral influence channel. A misleading or adversarial interaction could cause an inferred value to be stored and silently applied to future unrelated requests. ### Attack Path 1. A conversation contains a one-time request for a particular language, aspect ratio, or rendering behavior. 2. The Agent interprets that request as a recurring preference. 3. Following the Skill instructions, it runs `wayinvideo config set`. 4. The value is saved in `~/.wayinvideo/config.json`. 5. Future tasks resolve omitted command-line options from this persistent value. 6. Later output is altered without the user realizing that a previous interaction changed the global defaults. ### ...[truncated 496 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
wayinvideo-cli/wayinvideo/client.py:35
Finding

Bearer API Key Can Be Forwarded Across HTTP Redirects

Content
View full analysis
`. 2. The endpoint, a compromised intermediary, or a misconfigured service ...[truncated 833 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
wayinvideo-cli/wayinvideo/client.py:82
Finding

Local Video Contents Are Uploaded to an Unvalidated Server-Provided URL

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:81
Finding

Documented Curl Command Allows Shell Argument Injection

Content
View full analysis
--project-id ` again to refresh it. 2. **Provide the Link**: Always include the `export_link` as a clickable Markdown link. **NEVER** truncate, shorten, or alter these links. 3. **Download**: If the user wants to download the video or use it locally, use: `curl -L -o ""`. ``` ### Technical Analysis The suggested command interpolates a filename directly into shell syntax without quoting it. If the filename contains whitespace, shell operators, substitutions, or option-like content, it can change how the command is interpreted. The export link is quoted, which reduces ordinary shell parsing risk, but the instruction also requires the link to be used without alteration. A malicious or compromised API response containing quote-breaking content could become dangerous if an Agent directly substitutes it into a shell command. Because the Skill instructs an Agent to construct and execute this command, the unsafe template creates a command-injection path even though the Python CLI itself uses argument arrays for its OpenClaw subprocess call. ### Attack Path 1. A user or upstream result supplies a crafted output filename, such as one containing shell metacharacters. 2. The Agent substitutes that value for `` in the documented command. 3. The command is passed to a shell. 4. The shell interprets the injected syntax rather than treating the entire filename as data. 5. Attacker-selected commands execute with the privileges of the Agent process. A similar path exists if a compromise ...[truncated 612 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
wayinvideo-cli/wayinvideo/cli.py:80
Finding

Sensitive Video Results Are Persisted Without Enforced Owner-Only Permissions

Content
View full analysis
Remediation
View remediation
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (19)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill exposes significant capabilities through shell execution, network access, file reads/writes, and environment-variable use, but does not declare any explicit tool scope or permission boundary. That increases the chance the agent invokes the skill in contexts broader than intended, with insufficient review of sensitive actions such as local file access, API-key use, or downloads.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation text is overly broad and can cause the skill to trigger for almost any video-related request, including cases where local or safer processing would be more appropriate. In context, this skill can upload local files, poll remote jobs, persist settings, and download outputs, so over-triggering increases the risk of unnecessary data exposure or unintended side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill tells the agent to infer user preferences from prior interactions and persist them globally without explicit consent. This creates a privacy and autonomy risk because language, subtitle, or formatting preferences may be stored across tasks unexpectedly, potentially affecting future work or revealing inferred user attributes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The workflow explicitly instructs saving summaries and full transcripts to a local project folder, but it provides no warning about data retention, sensitivity, or cleanup. Video transcripts and summaries can contain personal data, confidential business information, or regulated content, so silently persisting them to disk increases the risk of unintended disclosure through shared machines, backups, or later reuse.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/platform_duration.md (reported line 1)May include surrounding context.

md
| Platform                | Max Duration (Official)                                                                                              | Recommended Duration (WayinVideo Param)                                      |
| :---------------------- | :------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- |
| **TikTok**              | Up to **10 min** when recording in-app; up to **60 min** when uploading                                              | `DURATION_0_90` for short-form; `DURATION_180_300` for extended storytelling |
| **Instagram Reels**     | Up to **20 min**                                                                                                     | `DURATION_0_90`                                                              |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/platform_duration.md (reported line 4)May include surrounding context.

md
| Platform                | Max Duration (Official)                                                                                              | Recommended Duration (WayinVideo Param)                                      |
| :---------------------- | :------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- |
| **TikTok**              | Up to **10 min** when recording in-app; up to **60 min** when uploading                                              | `DURATION_0_90` for short-form; `DURATION_180_300` for extended storytelling |
| **Instagram Reels**     | Up to **20 min**                                                                                                     | `DURATION_0_90`                                                              |
| **YouTube Shorts**      | Up to **3 min**                                                                                                      | `DURATION_0_90` or `DURATION_90_180`                                         |
| **X**                   | Up to **140 sec** for non-Premium; up to **4 hours** on web/iOS for Premium; up to **10 min** on Android for Premium | `DURATION_30_60` or `DURATION_90_180`                                        |
| **Facebook Reels**      | **Facebook now shares all videos as Reels**; no single 90-sec universal cap should be used                           | `DURATION_0_90`                                                              |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/platform_duration.md (reported line 8)May include surrounding context.

md
| Platform                | Max Duration (Official)                                                                                              | Recommended Duration (WayinVideo Param)                                      |
| :---------------------- | :------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- |
| **TikTok**              | Up to **10 min** when recording in-app; up to **60 min** when uploading                                              | `DURATION_0_90` for short-form; `DURATION_180_300` for extended storytelling |
| **Instagram Reels**     | Up to **20 min**                                                                                                     | `DURATION_0_90`                                                              |
| **YouTube Shorts**      | Up to **3 min**                                                                                                      | `DURATION_0_90` or `DURATION_90_180`                                         |
| **X**                   | Up to **140 sec** for non-Premium; up to **4 hours** on web/iOS for Premium; up to **10 min** on Android for Premium | `DURATION_30_60` or `DURATION_90_180`                                        |
| **Facebook Reels**      | **Facebook now shares all videos as Reels**; no single 90-sec universal cap should be used                           | `DURATION_0_90`                                                              |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/platform_duration.md (reported line 5)May include surrounding context.

md
| :---------------------- | :------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- |
| **TikTok**              | Up to **10 min** when recording in-app; up to **60 min** when uploading                                              | `DURATION_0_90` for short-form; `DURATION_180_300` for extended storytelling |
| **Instagram Reels**     | Up to **20 min**                                                                                                     | `DURATION_0_90`                                                              |
| **YouTube Shorts**      | Up to **3 min**                                                                                                      | `DURATION_0_90` or `DURATION_90_180`                                         |
| **X**                   | Up to **140 sec** for non-Premium; up to **4 hours** on web/iOS for Premium; up to **10 min** on Android for Premium | `DURATION_30_60` or `DURATION_90_180`                                        |
| **Facebook Reels**      | **Facebook now shares all videos as Reels**; no single 90-sec universal cap should be used                           | `DURATION_0_90`                                                              |
| **LinkedIn**            | Up to **15 min**                                                                                                     | `DURATION_90_180` or `DURATION_180_300`                                      |

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code emits external system notifications through a separate executable unrelated to the core stated purpose of the skill. That creates an unexpected outbound channel for task metadata and local file paths, which could disclose sensitive information or be abused in environments where system events are monitored, relayed, or automated. In the context of a video-processing CLI, this hidden side-channel is more dangerous because users would not reasonably expect it.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

The CLI invokes an external executable, openclaw, and forwards task IDs, statuses, and save-file paths into system events. Although subprocess.run is used without shell=True, this still expands the tool's capabilities beyond video processing and can leak workflow metadata or trigger unintended side effects on systems where openclaw is present. The skill context makes this more suspicious because external system notification is not essential to video editing and analysis.

Content

Scanner excerpt · wayinvideo-cli/wayinvideo/cli.py (reported line 71)May include surrounding context.

python
"""Fire an openclaw system event (best-effort, never raises)."""
    # Only send if event_enabled = True and event_enabled > 0, which is False and 0 by default.
    try:
        subprocess.run([
            "openclaw", "system", "event",
            "--text", text,
            "--mode", "now"

Cloud Storage Exfiltration

Medium
Category
Data Exfiltration
Confidence
55% confidence
Finding

Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.

Content

Scanner excerpt · wayinvideo-cli/wayinvideo/cli.py (reported line 107)May include surrounding context.

python
def _cmd_upload(args):
    print(f"Uploading {args.file_path} …", file=sys.stderr)
    try:
        identity = client.upload_file(args.file_path)
    except Exception as e:
        print(f"Upload failed: {e}", file=sys.stderr)
        sys.exit(1)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Submitted task payloads are written to disk by default, including video URLs, identity tokens, target language, search queries, and other request metadata. Persisting this information without clear user-facing disclosure increases the risk of local data exposure through shared accounts, backups, logs, or malware reading the cache directory. In this skill context, payloads may contain private media references or one-time upload identities, making default persistence more sensitive.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The polling loop stores raw API responses to disk by default, which may include transcripts, summaries, clips, export URLs, timestamps, and other potentially sensitive media-derived data. Because this happens automatically and repeatedly, it creates a durable local record of potentially private content without strong disclosure or minimization. For a tool handling user videos, this materially increases confidentiality risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

The CLI auto-generates and reuses local result files, creating persistent session artifacts by default. While persistence can be useful, in this implementation it stores operational state and potentially sensitive results without requiring explicit consent, increasing the chance of unintended retention and later disclosure. In a media-analysis tool, saved transcripts, summaries, and task metadata may contain private user content.

Content

Scanner excerpt · wayinvideo-cli/wayinvideo/cli.py (reported line 963)May include surrounding context.

python
pg = p_po.add_mutually_exclusive_group()
    pg.add_argument(
        "--save-file", metavar="PATH",
        help="Result JSON file to read/write (auto-generated if omitted)",
    )
    pg.add_argument(
        "--no-save", action="store_true",

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The guidance instructs use of curl to download arbitrary export content to a local filename without warning that this writes to disk or recommending safe handling. While not inherently malicious, it can surprise users, overwrite files, or persist potentially sensitive media locally in environments where filesystem side effects matter.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file documents operations that export rendered video clips and save a result JSON to disk, including a default cache path. Under the markdown-specific warning rule, user-facing documentation should disclose behaviors that affect user data or filesystem state, but no warning or caution is provided here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The markdown states 'English is preferred for better matching,' which creates a language preference in the skill guidance without offering a user choice or documenting a justified locale-specific constraint. This can conflict with organizational language/locale policy when users may reasonably expect equal support for other languages.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · wayinvideo-cli/wayinvideo/cli.py (reported line 61)May include surrounding context.

python
def _resolve_flag(args, attr, config_key, fallback):
    """Resolve a --flag / --no-flag pair (True / False / None in namespace)."""
    val = getattr(args, attr, None)
    if val is not None:
        return val
    return _resolve(None, config_key, fallback)

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The _send_event documentation and inline comment imply the function itself only sends events when event_enabled is true and positive, with disabled behavior by default. In reality, _send_event unconditionally runs the external command whenever called; the gating happens elsewhere in polling logic, so the inline documentation misstates the function's behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.