Back to skill

Security audit

Medeo Video

Security checks for vulnerabilities and agentic risk

Overview

This video-generation skill mostly matches its stated purpose, but it has serious review-worthy risks around command execution, credential handling, external messaging, and unrestricted URL fetching.

Review carefully before installing. Only use this in an environment where the Medeo, Feishu, Telegram, and Discord credentials are scoped to this workflow, avoid sending API keys in ordinary chat, rotate any token that may appear in logs, and do not let untrusted users supply prompts or URLs until the command-construction and URL-fetch issues are fixed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/medeo_video.py:843
Finding

Shell Command Injection in Asynchronous Worker Command Construction

Content
View full analysis
compose -> render) and typically takes 5-30 minutes. " "Wait for the command to complete — do NOT background it.\n\n" "When the command finishes:\n" "- If the JSON output contains \"status\": \"completed\":\n" " 1. Extract \"video_url\", \"thumbnail_url\", and " "\"total_duration_seconds\" from the JSON output.\n" "{delivery_instructions}\n" " 3. Always include a short text summary: prompt used, " "duration, resolution.\n" "- If the error indicates insufficient credits (" "in ...[truncated 2495 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/medeo_video.py:1187
Finding

Server-Side Request Forgery and External Data Relay Through Unrestricted URL Fetching

Content
View full analysis
MAX_UPLOAD_SIZE: print(json.dumps({ "error": f"Downloaded file too large (max {MAX_UPLOAD_SIZE // 1024 // 1024} MB)", "hint": "Try a smaller image or video.", }), file=sys.stderr) sys.exit(1) chunks.append(chunk) file_bytes = b"".join(chunks) ``` ```python def upload_cover(token, cover_source): """Upload cover image, return image_key. cover_source can be a local path or URL.""" if cover_source.startswith("http"): # Download from URL img_resp = requests.get(cover_source, timeout=30) img_resp.raise_for_status() img_data = img_resp.content filename = "cover.jpg" else: with open(cover_source, "rb") as f: img_data = f.read() filename = os.path.basename(cover_source) resp = requests.post( "https://open.feishu.cn/open-apis/im/v1/images", headers={"Authorization": f"Bearer {to ...[truncated 2662 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/medeo_video.py:1254
Finding

Telegram Bot Token Disclosure Through Authenticated URL Logging

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/medeo_video.py:1560
Finding

Medeo API Key Exposed Through Command-Line Setup and Insecure Plaintext File Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
docs/assets-upload.md:49
Finding

Documentation Encourages Messaging Token Transmission Through Command-Line Arguments

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded Third-Party Dependency Version Range

Content
View full analysis
=2.20.0 ``` ### Technical Analysis The dependency specification permits any `requests` release newer than or equal to version 2.20.0, including future major or otherwise unreviewed releases. No lock file or package hashes are provided. This does not establish that the current dependency is malicious. However, it makes installations non-reproducible and allows the effective dependency code to change after the Skill itself has been audited. It also increases exposure to future compromised releases, regressions, or incompatible transitive dependency resolution. ### Attack Path 1. The Skill is installed or rebuilt at a later date. 2. The package resolver selects a newer version that was not included in the reviewed artifact. 3. That version or one of its transitive dependencies contains a compromise or security regression. 4. The package is imported by the Skill and executes with the Agent runtime's privileges. 5. The compromised dependency gains access to network traffic, API keys, uploaded files, and process state handled by the Skill. ### Impact Assessment A compromised dependency could operate with the same privileges as the video-generation scripts. This may expose: - Medeo and messaging credentials available to the process. - User prompts and uploaded media. - Local files readable by the runtime account. - Outbound API requests and returned media metadata. The finding represents supply-chain exposure rather than proof of an existing malicious package. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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 (47)

YARA rule 'agent_skill_credential_exfiltration_webhook': AI agent skill credential harvesting followed by webhook or external exfiltration [agent_skills]

Critical
Category
YARA Match
Confidence
85% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

python
t(1)


# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------

STATE_DIR = Path(os.path.expanduser("~/.openclaw/workspace/medeo-video"))
CONFIG_FILE = STATE_DIR / "config.json"
LAST_JOB_FILE = STATE_DIR / "last_job.json"
HISTORY_DIR = STATE_DIR / "history"

# Defaults
DEFAULT_ENV = os.environ.get("MEDEO_ENV", "prd")

ENV_DEFAULTS = {
    "prd": {
        "baseUrl": "https://api.prd.medeo.app",
        "ossBaseUrl": "https://oss.prd.medeo.app",
        "apiKeyUrl": os.environ.get(
            "MEDEO_SIGNUP_URL",
            "https://medeo.app/dev/apikey",
        ),
    },
}

# Top-up / recharge URL (for insufficient credits)
MEDEO_TOPUP_URL = os.environ.get("MEDEO_TOPUP_URL", "https://medeo.app/")

# Network
CONNECT_TIMEOUT = 15   # seconds — TCP handshake
READ_TIMEOUT = 60      # seconds — wait for response body
MAX_RETRIES = 2

# Polling
POLL_INITIAL_INTERVAL = 3

Tainted flow: 'api_key' from os.environ.get (line 249, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/medeo_video.py (reported line 339)May include surrounding context.

python
for attempt in range(MAX_RETRIES + 1):
        try:
            resp = requests.get(
                url,
                headers=_headers(api_key),
                params=params,

Tainted flow: 'api_key' from os.environ.get (line 249, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/medeo_video.py (reported line 407)May include surrounding context.

python
for attempt in range(MAX_RETRIES + 1):
        try:
            resp = requests.post(
                url,
                headers=_headers(api_key, idem_key),
                json=body,

Tainted flow: 'token' from os.environ.get (line 1231, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/medeo_video.py (reported line 1240)May include surrounding context.

python
}), file=sys.stderr)
            sys.exit(1)
        _log(f"Fetching Telegram file info: {args.telegram_file_id}")
        r = requests.get(
            f"https://api.telegram.org/bot{token}/getFile",
            params={"file_id": args.telegram_file_id},
            timeout=(CONNECT_TIMEOUT, READ_TIMEOUT),

Tainted flow: 'dl_url' from os.environ.get (line 1254, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The code logs the full Telegram download URL, which embeds the bot token directly in the path. Any stderr capture, task logs, or observability pipeline would then contain a reusable secret that can be abused to access the bot API.

Content

Scanner excerpt · scripts/medeo_video.py (reported line 1256)May include surrounding context.

python
filename = f"tg_{args.telegram_file_id[:12]}.{extension}"
        dl_url = f"https://api.telegram.org/file/bot{token}/{file_path}"
        _log(f"Downloading Telegram file: {dl_url}")
        r2 = requests.get(dl_url, timeout=(CONNECT_TIMEOUT, 60))
        r2.raise_for_status()
        file_bytes = r2.content
        _log(f"Downloaded {len(file_bytes)} bytes from Telegram")

Tainted flow: 'feishu_token' from os.environ.get (line 1267, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/medeo_video.py (reported line 1273)May include surrounding context.

python
file=sys.stderr)
            sys.exit(1)
        _log(f"Downloading Feishu image: msg={args.feishu_message_id} key={args.feishu_image_key}")
        r = requests.get(
            f"https://open.feishu.cn/open-apis/im/v1/messages/{args.feishu_message_id}/resources/{args.feishu_image_key}",
            params={"type": "image"},
            headers={"Authorization": f"Bearer {feishu_token}"},

Tainted flow: 'token' from os.environ.get (line 46, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/telegram_send_video.py (reported line 102)May include surrounding context.

python
except Exception as exc:
                print(f"[telegram] Thumbnail download error: {exc}, skipping", file=sys.stderr)

        resp = requests.post(
            f"{TELEGRAM_API_BASE}/bot{token}/sendVideo",
            data=data,
            files=files,

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims only media-generation functions, yet it also includes Telegram delivery behavior involving token-based messaging, network transmission, and local file handling. Undeclared outbound communication channels materially change the risk profile because generated or downloaded content may be sent to third-party destinations without clear user awareness.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims only media-generation functions, yet it also includes Telegram delivery behavior involving token-based messaging, network transmission, and local file handling. Undeclared outbound communication channels materially change the risk profile because generated or downloaded content may be sent to third-party destinations without clear user awareness.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly tells the user to send their Medeo API key back in chat, then configures the system from that value. Secret collection via ordinary chat is dangerous because chat logs, platform history, and internal observability systems may retain or expose the credential long after setup.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The first-time setup section repeats the instruction for the user to provide their API key directly to the agent, reinforcing insecure secret-handling as the normal workflow. Repetition makes misuse more likely and normalizes transmission of bearer credentials through potentially monitored channels.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This file implements outbound Feishu messaging and media upload, which is operationally distinct from a video-generation skill and expands the skill into enterprise chat delivery. That mismatch increases the risk of covert data exfiltration or unauthorized messaging because generated or local media can be silently transmitted to external recipients.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/feishu_send_video.py (reported line 62)May include surrounding context.

python
def get_tenant_token():
    """Get tenant access token from Feishu."""
    app_id, app_secret = get_feishu_credentials()
    resp = requests.post(
        "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The README explicitly states that generation runs in the background and that the assistant will later send the completed video, which implies session persistence and deferred actions across turns. If not tightly scoped and authorized, persistent jobs and later callbacks can act on stale context, deliver content after user intent has changed, or continue using stored credentials without fresh confirmation.

Content

Scanner excerpt · README.md (reported line 3)May include surrounding context.

md
# 🎬 Medeo Video Generator

Generate AI-powered videos from text. Tell your AI assistant "make me a video about XX" and it will automatically create the video using the [Medeo](https://medeo.app) platform, sending you the result in a few minutes.

---

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README advertises a very broad natural-language trigger, "make me a video about XX," which can overlap with ordinary conversation and cause the assistant to invoke the skill unexpectedly. In an agent ecosystem, ambiguous triggers increase the chance of unintentional external API calls, uploads, or job creation without the user clearly intending to use this specific skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The usage examples rely on generic phrases like "Make me a video" and "Use this image to create a product promo video," without distinguishing when the skill should activate versus when the assistant should respond normally. This ambiguity can lead to accidental activation, unintended asset handling, and external processing of user content.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill exercises powerful capabilities including shell execution, filesystem access, environment-variable use, and network communication, but it declares no explicit tool scope or permission boundaries. In practice this increases the blast radius of prompt injection or misuse because reviewers and runtime policy cannot easily constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill directs the agent to read ~/.openclaw/openclaw.json for Feishu credentials unrelated to Medeo and then use them to call Feishu APIs directly. Accessing unrelated local credentials expands privilege across account boundaries and creates a clear path for unauthorized outbound messaging or abuse of existing channel integrations.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This code performs external transmission to Feishu's authentication endpoint using locally read app credentials. Although the destination is expected, it still sends sensitive authentication material off-host and, combined with direct credential file access, creates a meaningful exfiltration and misuse surface if the skill is repurposed or manipulated.

Content

Scanner excerpt · SKILL.md (reported line 30)May include surrounding context.

md
import json, urllib.request
cfg = json.loads(open("/home/ec2-user/.openclaw/openclaw.json").read())
feishu = cfg["channels"]["feishu"]["accounts"]["default"]
token = json.loads(urllib.request.urlopen(urllib.request.Request(
    "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
    data=json.dumps({"app_id": feishu["appId"], "app_secret": feishu["appSecret"]}).encode(),
    headers={"Content-Type": "application/json"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

This step sends an externally delivered Feishu message containing setup instructions, including a request for the user to return an API key in chat. The transmission itself is expected for messaging, but in context it facilitates insecure secret collection and demonstrates undeclared outbound communications beyond the core video-generation role.

Content

Scanner excerpt · SKILL.md (reported line 40)May include surrounding context.

md
"header": {"title": {"tag": "plain_text", "content": "🎬 Video Generation — API Key Required"}, "template": "blue"},
    "elements": [{"tag": "div", "text": {"tag": "lark_md", "content": "You need a **Medeo API Key** to generate videos.\n\n**Steps:**\n1. Go to https://medeo.app/dev/apikey\n   - No account? You'll be guided to sign up. The key appears after login.\n2. Copy the key (starts with `mk_`) and send it back to me.\n\nOnce I have it, I'll configure everything for you."}}],
}
urllib.request.urlopen(urllib.request.Request(
    "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id",
    data=json.dumps({"receive_id": "<USER_OPEN_ID>", "msg_type": "interactive", "content": json.dumps(card)}).encode(),
    headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup flow has the user transmit their Medeo API key back through chat so the agent can store it locally, without a prominent warning about sensitivity, retention, or safer alternatives. Collecting API secrets in normal conversation channels increases the chance of leakage through logs, transcripts, channel history, or operator visibility.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill instructs users to upload attachments and later stores operational artifacts such as job history locally, but it does not provide a user-facing notice about local persistence. Lack of transparency around storage of media and metadata can expose sensitive personal content and create compliance or privacy issues.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% 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 · SKILL.md (reported line 284)May include surrounding context.

md
1. **Always async** — `spawn-task` + `sessions_spawn` for generation
2. **One call for stories** — full storylines in one `--message`, never split
3. **Insufficient credits** — share recharge link from error output
4. **IM image upload** — Only upload images when the user explicitly asks for video generation with that image. Do NOT auto-upload every image message (user may have other skills installed). When triggered: run `upload-file` first → get `media_id` → pass to generation via `--media-ids`. Never ask the user for a URL if they already sent the image.
5. **IM-native delivery** — After generation, deliver the video using the IM channel's native method (not just a URL). Each channel has a dedicated delivery script:
   - **Feishu**: `python3 {baseDir}/scripts/feishu_send_video.py --video /tmp/result.mp4 --to "oc_xxx_or_ou_xxx" --cover-url "<thumbnail_url>" --duration <ms>` (use `oc_` chat_id for group chats, `ou_` open_id for private chats; `chat:oc_xxx` and `user:ou_xxx` prefixed forms are also accepted)
   - **Telegram**: Download video, then send via `telegram_send_video.py` (token from env only):

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill bundles broad multi-platform outbound delivery and bot-token messaging instructions beyond its stated video-generation role. This materially increases attack surface because the skill can move content across services and use bot credentials without clear least-privilege boundaries.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The security note claims no legacy system-level files are read, yet the documented workflow explicitly reads ~/.openclaw/openclaw.json for Feishu credentials. Misleading security documentation can cause reviewers and users to underestimate exposure and approve a skill that accesses more sensitive local state than disclosed.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.