T01 · Skill Instruction Hijacking
- 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
Security audit
Security checks for vulnerabilities and agentic risk
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.
SKILL.md:99Skill Instructions Suppress Consent Before External Actions
SKILL.md:73Inferred User Preferences Are Persisted Globally Without Explicit Opt-In
wayinvideo-cli/wayinvideo/client.py:35Bearer API Key Can Be Forwarded Across HTTP Redirects
wayinvideo-cli/wayinvideo/client.py:82Local Video Contents Are Uploaded to an Unvalidated Server-Provided URL
SKILL.md:81Documented Curl Command Allows Shell Argument Injection
wayinvideo-cli/wayinvideo/cli.py:80Sensitive Video Results Are Persisted Without Enforced Owner-Only Permissions
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.
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.
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.
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.
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.
| 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` |
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.
| 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` |
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.
| 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` |
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.
| :---------------------- | :------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- |
| **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` |
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.
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.
"""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"
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.
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)
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.
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.
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.
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",
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.
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.
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.
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.
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)
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.
No suspicious patterns detected.