Back to skill

Security audit

Xiao Hong Shu Video Analyser

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it needs Review because its downloader can fetch arbitrary non-Xiaohongshu URLs and it sends extracted audio to a third-party transcription API.

Install only if you are comfortable sending the video's audio to Poe/Gemini for transcription and storing the video, audio, chunks, and transcript locally. Use it only with intended Xiaohongshu URLs, avoid running it with elevated privileges, and prefer a private trusted work directory until URL validation and temporary-file handling are tightened.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/download.py:18
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/download.py, lines 18-32
Vulnerability Type: Server-Side Request Forgery through insufficient URL validation
Risk Level: Medium

Vulnerable Code

python
# 提取 note ID
note_id_match = re.search(r'xiaohongshu\.com/explore/([a-f0-9]+)', url)
if not note_id_match:
    note_id_match = re.search(r'xiaohongshu\.com/discovery/item/([a-f0-9]+)', url)

note_id = note_id_match.group(1) if note_id_match else None

try:
    # 方法1: 使用 API
    if note_id:
        api_url = f"https://www.xiaohongshu.com/discovery/item/{note_id}"
        resp = requests.get(api_url, headers=headers, timeout=30)
    else:
        resp = requests.get(url, headers=headers, timeout=30)

Technical Analysis

The Skill is declared to process Xiaohongshu URLs, but URLs that do not match the expected Xiaohongshu path patterns are fetched directly. The fallback branch does not validate:

  • The URL scheme
  • The exact destination hostname
  • Embedded credentials or nonstandard ports
  • Whether the hostname resolves to a loopback, private, link-local, or reserved address
  • Redirect destinations

Python Requests follows redirects by default. Consequently, even an initially permitted destination could redirect the request to an internal service.

The response body is not directly returned to the caller, which limits straightforward data extraction. However, the request still originates from the Agent's network context and can be used for blind internal-service probing. If a fetched response has the expected Xiaohongshu state structure, extracted media URLs may also cause subsequent outbound requests.

Attack Path

  1. An attacker supplies a URL targeting an internal service, loopback interface, cloud metadata endpoint, or attacker-controlled redirector.
  2. The Agent invokes full-analyze.sh with that URL.
  3. The URL does not match either expected Xiaohongshu path expressio ...[truncated 1072 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse input with urllib.parse.urlsplit() rather than relying on substring-oriented regular expressions.
  2. Require HTTPS and an exact hostname allowlist, such as www.xiaohongshu.com.
  3. Reject URLs containing embedded credentials, unexpected ports, malformed hostnames, or unsupported paths.
  4. Resolve the hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IP ranges for both IPv4 and IPv6.
  5. Disable redirects with allow_redirects=False, or validate every redirect target using the same scheme, hostname, port, and resolved-address checks.
  6. Apply destination validation again before downloading an extracted media URL.
  7. Consider enforcing outbound network policy outside the application so the process cannot contact local, private, or metadata address ranges.
  8. Call raise_for_status() and impose response-size limits to reduce abuse and resource-consumption risks.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/full-analyze.sh:7
Finding

Predictable Work Directory and Fixed Output Names Permit Symlink File Clobbering

Content
View full analysis

Vulnerability Details

File Location: scripts/full-analyze.sh, lines 7-19, with vulnerable writes at lines 98 and 109
Vulnerability Type: Unsafe temporary-directory and file handling
Risk Level: Medium

Vulnerable Code

bash
WORK_DIR="${2:-/tmp/xhs-analysis-$(date +%s)}"

if [ -z "$URL" ]; then
    echo "Usage: $0 <xhs_url> [work_dir]"
    exit 1
fi

# 获取脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# 创建工作目录
mkdir -p "$WORK_DIR"
cd "$WORK_DIR"

The script later opens predictable filenames inside that directory:

bash
mkdir -p transcripts
TRANSCRIPT_FILE="audio.txt"
> "$TRANSCRIPT_FILE"
bash
cat > request.json << EOF

Technical Analysis

The default work-directory name contains only the current Unix timestamp in seconds, making it predictable. The script uses mkdir -p, which accepts an already existing directory without verifying its owner, permissions, or whether it was created by another process.

The optional work-directory argument also permits a caller to select an existing directory. Once inside the directory, the script creates or truncates fixed filenames such as audio.txt and request.json without checking whether they are symbolic links or other unexpected filesystem objects.

If another local user or process can pre-create the predicted directory and place symlinks at these paths, shell redirection follows those symlinks. The target is then truncated or overwritten with the privileges of the account running the Skill. Similar risks apply to other fixed output names processed by Python, ffmpeg, yt-dlp, and shell commands.

The script also does not set a restrictive umask, so generated video, audio, request, chunk, and transcript files may be readable by other local users depending on the invoking environment's default permissions.

Attack Path

  1. A local attacker predicts the default d ...[truncated 1446 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create a unique private directory with mktemp -d, for example:
    bash
    umask 077
    WORK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/xhs-analysis.XXXXXXXX")"
    
  2. If a caller-supplied directory must be supported, require it not to exist and create it atomically with mode 0700.
  3. Reject directories that are symbolic links, are not owned by the invoking user, or are writable by untrusted users.
  4. Before opening fixed output paths, verify that they do not already exist. Where practical, create files atomically with exclusive-create semantics.
  5. Avoid shell redirection to paths that may be attacker-controlled. Generate request data through a safely created temporary file or send it directly to curl through standard input.
  6. Set umask 077 before creating media, transcript, chunk, and request files.
  7. Add a guarded trap to delete transient request files and other sensitive temporary artifacts on normal exit, error, or interruption.
  8. Avoid running the Skill as root or another privileged account; use a dedicated account with minimal filesystem and network access.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill description omits important behaviors: contacting third-party services, reading API credentials from local config or environment, and persisting downloaded and transcribed content on disk. These hidden behaviors increase privacy and security risk because sensitive user-provided media and derived transcripts may be stored or transmitted without clear disclosure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill description omits important behaviors: contacting third-party services, reading API credentials from local config or environment, and persisting downloaded and transcribed content on disk. These hidden behaviors increase privacy and security risk because sensitive user-provided media and derived transcripts may be stored or transmitted without clear disclosure.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/full-analyze.sh (reported line 129)May include surrounding context.

sh
EOF
        
        # 发送请求
        response=$(curl -sS https://api.poe.com/v1/chat/completions \
            -H "Authorization: Bearer $POE_API_KEY" \
            -H "Content-Type: application/json" \
            -d @request.json 2>&1)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
97% confidence
Finding

The skill invokes shell scripts and performs network access, but the manifest does not declare any tool scope or permissions. This creates an authorization gap where users and the host agent are not clearly informed that the skill will execute shell commands and communicate externally, increasing the chance of unintended command execution and data transfer.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill sends audio derived from the user's video to Poe/Gemini for cloud transcription, but the user-facing description does not warn that content leaves the local environment. This is a privacy vulnerability because uploaded audio may contain sensitive personal, business, or copyrighted material, and users are deprived of meaningful consent.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The skill is configured to transmit data to an external service endpoint, which is expected for cloud transcription but still introduces data-exposure risk. In this context the danger is elevated because the transmitted content includes user-derived audio and possibly metadata, and the external transmission is not prominently disclosed up front.

Content

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

md
"models": {
    "providers": {
      "poe": {
        "baseUrl": "https://api.poe.com/v1",
        "apiKey": "YOUR_POE_API_KEY"
      }
    }

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script reads a Poe API key from ~/.openclaw/openclaw.json if the environment variable is unset, causing the skill to reach into unrelated user configuration and silently reuse credentials. This expands access beyond the stated purpose and can surprise users by using sensitive local secrets for a third-party service without explicit consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The request text instructs the model to transcribe only Chinese content, which imposes a specific language behavior without any user choice. This can violate language/locale policy expectations when the skill is used on multilingual or non-Chinese audio.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The hardcoded api.poe.com endpoint confirms that processing depends on a third-party service, so user audio leaves the local system. This is especially relevant because the skill description emphasizes download and analysis, but does not prominently warn about external data transfer.

Content

Scanner excerpt · scripts/full-analyze.sh (reported line 129)May include surrounding context.

sh
EOF
        
        # 发送请求
        response=$(curl -sS https://api.poe.com/v1/chat/completions \
            -H "Authorization: Bearer $POE_API_KEY" \
            -H "Content-Type: application/json" \
            -d @request.json 2>&1)

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The hardcoded api.poe.com endpoint confirms that processing depends on a third-party service, so user audio leaves the local system. This is especially relevant because the skill description emphasizes download and analysis, but does not prominently warn about external data transfer.

Content

Scanner excerpt · scripts/full-analyze.sh (reported line 129)May include surrounding context.

sh
EOF
        
        # 发送请求
        response=$(curl -sS https://api.poe.com/v1/chat/completions \
            -H "Authorization: Bearer $POE_API_KEY" \
            -H "Content-Type: application/json" \
            -d @request.json 2>&1)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script base64-encodes each audio chunk and sends it to api.poe.com for transcription, which transfers potentially sensitive spoken content off-device. There is no explicit warning, consent step, or data-handling notice, so users may unknowingly disclose private audio to a third-party provider.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instruction '使用流畅的中文表达' requires summaries to be written in Chinese, which is a fixed language constraint. Because the document does not offer a language option or explain that the skill is intentionally Chinese-only for a justified regional purpose, this is a natural-language locale policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The HTTP header hard-codes Accept-Language to prefer zh-CN, which imposes a specific locale behavior rather than allowing the user's own language or system preference. This is a natural-language policy issue because the skill does not provide any opt-in or configuration for locale selection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script accesses API credentials from environment variables and a local config file without clear disclosure to the user. While credential loading itself is common, silently sourcing secrets from user context reduces transparency and can lead to unintended account usage or billing.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.