Back to skill

Security audit

Video Summarizer(视频摘录+Notion/Obsidian知识库存档)

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated video-summary purpose, but a real command-execution flaw in its output-directory handling makes it require review before use.

Install only after the output-directory injection is fixed. Until then, do not let untrusted text, links, or automation choose the output directory, and use dedicated least-privilege API keys, a dedicated OSS bucket, and non-sensitive videos because transcripts and media artifacts may be sent to configured third-party services.

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/video-summarize.sh:466
Finding
Arbitrary Python Code Execution Through Output Directory Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/video-summarize.sh`, lines 466-470 **Vulnerability Type**: User-controlled path interpolated into dynamically evaluated Python source **Risk Level**: High ### Vulnerable Code ```bash TITLE=$($PYTHON -c "import json; print(json.load(open('$OUTPUT_DIR/metadata.json')).get('title', 'Unknown'))" 2>/dev/null || echo "Unknown") UPLOADER=$($PYTHON -c "import json; print(json.load(open('$OUTPUT_DIR/metadata.json')).get('uploader', 'Unknown'))" 2>/dev/null || echo "Unknown") DURATION=$($PYTHON -c "import json; print(json.load(open('$OUTPUT_DIR/metadata.json')).get('duration_string', 'Unknown'))" 2>/dev/null || echo "Unknown") DURATION_SEC=$($PYTHON -c "import json; print(int(json.load(open('$OUTPUT_DIR/metadata.json')).get('duration', 0)))" 2>/dev/null || echo "0") THUMBNAIL=$($PYTHON -c "import json; print(json.load(open('$OUTPUT_DIR/metadata.json')).get('thumbnail', ''))" 2>/dev/null || echo "") ``` The same unsafe interpolation pattern also appears at lines 917, 1006, and 1075. ### Technical Analysis The second positional command-line argument is accepted as `OUTPUT_DIR`. The `validate_output_dir()` function rejects `..` and a limited set of sensitive system directories, but does not reject quote characters or Python syntax. `OUTPUT_DIR` is subsequently inserted directly into source code supplied to `python -c`. Shell quoting does not make this safe because the shell first expands the variable into the double-quoted command argument, after which Python interprets the resulting string as executable source code. An attacker can include a single quote and Python expression syntax in the output directory. For example, a path shaped like the following can cause a function call to be evaluated while Python constructs the argument to `open()`: ```text /tmp/'+str(__import__('os').system('id'))+'x ``` This changes the effective Python expression and invokes `os.system()` before normal file handling finis ...[truncated 1370 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not construct executable Python source using interpolated paths. Pass all values through environment variables or command-line arguments. For example: ```bash OUTPUT_DIR="$OUTPUT_DIR" "$PYTHON" -c ' import json import os metadata_path = os.path.join(os.environ["OUTPUT_DIR"], "metadata.json") with open(metadata_path, encoding="utf-8") as metadata_file: print(json.load(metadata_file).get("title", "Unknown")) ' ``` A preferable long-term fix is to place metadata extraction in a dedicated Python script and pass the metadata path as a normal argument: ```bash "$PYTHON" "$SCRIPT_DIR/read-metadata-field.py" \ "$OUTPUT_DIR/metadata.json" title ``` Additional hardening should include: 1. Replace every path interpolated into `python -c`, including the patterns at lines 917, 1006, and 1075. 2. Reject control characters, newlines, and NUL bytes in user-supplied paths. 3. Canonicalize output paths before applying restricted-directory policies. 4. Add automated tests using paths containing single quotes, double quotes, spaces, newlines, shell metacharacters, and Python expression syntax. 5. Avoid relying on character blacklists as the primary injection defense; values should remain data rather than executable source. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/upload-to-oss.py:312
Finding
Predictable Shared Temporary File Enables Symlink Overwrite and Cross-Job Interference<![CDATA[ ## Vulnerability Details **File Location**: `scripts/upload-to-oss.py`, lines 312-314 **Vulnerability Type**: Insecure predictable temporary file creation **Risk Level**: Medium ### Vulnerable Code ```python temp_file = os.path.join(tempfile.gettempdir(), 'thumbnail_temp.jpg') with open(temp_file, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) ``` ### Technical Analysis Thumbnail downloads always use the same filename in the system temporary directory. The file is opened with `open(..., 'wb')`, which truncates an existing file and follows symbolic links. On multi-user systems, or when another process with the same user identity is compromised, an attacker can create the predictable path before the Skill runs and point it to another file through a symbolic link. When the thumbnail is downloaded, the target of that link is truncated and overwritten. The shared name also creates a time-of-check/time-of-use and cross-job race. Two concurrent Skill executions can write different thumbnails to the same path, delete each other’s temporary file, or cause one job to upload content written by another job. ### Attack Path 1. The attacker predicts the temporary path, normally `/tmp/thumbnail_temp.jpg` on Unix-like systems. 2. Before thumbnail processing begins, the attacker creates that path as a symbolic link to a file writable by the Skill user. 3. The Skill calls `open(temp_file, 'wb')`. 4. The operating system follows the symbolic link and truncates the linked target. 5. The downloaded thumbnail bytes are written into that target. 6. Alternatively, a concurrent process replaces or modifies the shared temporary file before it is uploaded to OSS. 7. The Skill may then upload attacker-selected or cross-job content and remove the shared path. ### Impact Assessment The vulnerability can overwrite arbitrary files writable by the Skill user. It can also cause: - Corruption of user-owned files - Cross-job thumb ...[truncated 368 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Create a unique temporary file atomically with restrictive permissions. Use `NamedTemporaryFile` or `mkstemp`, and ensure cleanup occurs in a `finally` block. For example: ```python import os import tempfile temp_path = None try: with tempfile.NamedTemporaryFile( mode="wb", prefix="video-summarizer-thumbnail-", suffix=".jpg", delete=False, ) as temp_file: temp_path = temp_file.name for chunk in response.iter_content(chunk_size=8192): if chunk: temp_file.write(chunk) result = upload_to_oss(temp_path, remote_key, public=public) finally: if temp_path: try: os.remove(temp_path) except FileNotFoundError: pass ``` Additional hardening should include: 1. Never reuse a global temporary filename across executions. 2. Keep temporary-file permissions restricted to the current user. 3. Place cleanup in `finally` so failures do not leave sensitive artifacts. 4. Enforce a maximum thumbnail download size to prevent unbounded temporary storage consumption. 5. Validate the downloaded response type before uploading it as an image. 6. Add concurrency tests to verify that simultaneous jobs cannot access, replace, or delete each other’s temporary files. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (116)

Tainted flow: 'video_info' from os.getenv (line 436, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
if show_progress:
            print(f"正在下载视频:{video_info['title']}")

        response = requests.get(video_info['url'], headers=HEADERS, stream=True)
        response.raise_for_status()

        # 获取文件大小
Confidence
96% confidence
Finding
The downloader fetches `video_info['url']`, which ultimately comes from remote page data, without validating the final download host or content type. If the upstream page is malicious or compromised, the tool can be turned into an SSRF or arbitrary-file download mechanism, causing retrieval of attacker-chosen content into the local filesystem.

Tainted flow: 'HEADERS' from os.getenv (line 33, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
def search_database(database_id):
    """查询 Notion Database(Data Source)"""
    url = f"https://api.notion.com/v1/data_sources/{database_id}/query"
    response = requests.post(url, headers=HEADERS, json={})
    if response.status_code == 200:
        return response.json()
    else:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'HEADERS' from os.getenv (line 33, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
for attempt in range(3):
        try:
            timeout = 30 * (attempt + 1)  # 30s, 60s, 90s
            response = requests.post(url, headers=HEADERS, json=data, timeout=timeout)
            if response.status_code == 200:
                break
            elif response.status_code == 400:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'HEADERS' from os.getenv (line 33, credential/environment) → requests.patch (network output)

Critical
Category
Data Flow
Content
for attempt in range(3):
        try:
            timeout = 30 * (attempt + 1)  # 30s, 60s, 90s
            response = requests.patch(url, headers=HEADERS, json={"children": blocks}, timeout=timeout)
            if response.status_code == 200:
                return True
            elif response.status_code == 400:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.getenv (line 131, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
with open(audio_file, 'rb') as f:
            files = {"file": f}
            data = {"model": "whisper-large-v3", "response_format": "verbose_json"}
            response = requests.post(url, headers=headers, files=files, data=data, timeout=600)
    except requests.exceptions.Timeout:
        return {'success': False, 'error': 'Groq API 超时'}
    except requests.exceptions.ConnectionError as e:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Credential Access

High
Category
Privilege Escalation
Content
venv/
env/
.venv/
.env.local

# 临时文件
*.log
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
1. **Step 1 元数据生成(抖音平台)**
   - ❌ 修复前:heredoc 直接展开 `$TITLE` 等变量,存在命令注入风险
   - ✅ 修复后:使用 Python `json.dump()` 安全生成 JSON(自动转义特殊字符)
   - 攻击场景:视频标题包含 `"; rm -rf ~ #` 等恶意内容时可执行任意命令

2. **save_progress() 函数**
   - ❌ 修复前:heredoc 直接展开 `$VIDEO_URL` 和 `$OUTPUT_DIR`
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Chaining Abuse

High
Category
Tool Misuse
Content
1. **Step 1 元数据生成(抖音平台)**
   - ❌ 修复前:heredoc 直接展开 `$TITLE` 等变量,存在命令注入风险
   - ✅ 修复后:使用 Python `json.dump()` 安全生成 JSON(自动转义特殊字符)
   - 攻击场景:视频标题包含 `"; rm -rf ~ #` 等恶意内容时可执行任意命令

2. **save_progress() 函数**
   - ❌ 修复前:heredoc 直接展开 `$VIDEO_URL` 和 `$OUTPUT_DIR`
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented workflow includes downloading full video/audio, extracting subtitles, generating screenshots, uploading media, and retaining logs and intermediate artifacts. In the context of an agent skill, this broad collection and persistence of user-requested media increases privacy and data-retention risk, especially when coupled with outbound AI analysis and cloud storage.

Ae1

High
Category
analysis-evasion
Content
| 编排层 | Bash (`video-summarize.sh`) |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| 编排层 | Bash (`video-summarize.sh`) |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
config.py - video-summarizer 统一配置(Python 端)
所有脚本 import config 即可获取环境变量和路径。

加载链:$AGENT_HOME/.env → $HERMES_HOME/.env → ~/.hermes/.env → ~/.openclaw/.env
"""

import os
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
config.py - video-summarizer 统一配置(Python 端)
所有脚本 import config 即可获取环境变量和路径。

加载链:$AGENT_HOME/.env → $HERMES_HOME/.env → ~/.hermes/.env → ~/.openclaw/.env
"""

import os
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
config.py - video-summarizer 统一配置(Python 端)
所有脚本 import config 即可获取环境变量和路径。

加载链:$AGENT_HOME/.env → $HERMES_HOME/.env → ~/.hermes/.env → ~/.openclaw/.env
"""

import os
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
config.py - video-summarizer 统一配置(Python 端)
所有脚本 import config 即可获取环境变量和路径。

加载链:$AGENT_HOME/.env → $HERMES_HOME/.env → ~/.hermes/.env → ~/.openclaw/.env
"""

import os
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

No suspicious patterns detected.