Back to skill

Security audit

Ephemeral Media Hosting

Security checks for vulnerabilities and agentic risk

Overview

This is a real temporary media-hosting guide, but it needs review because it can fetch arbitrary URLs from the server and may publicly expose uploader/source metadata.

Review before installing. Only deploy this after restricting remote fetches to trusted domains or blocking private/internal IP ranges and redirects, moving or denying .meta files from the public web root, minimizing IP/source URL/original filename retention, tightening directory permissions, and explicitly approving the sudo and cron steps.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:330
Finding

Server-Side Request Forgery Through Unrestricted Image Fetching

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:84
Finding

Public Exposure of Source URLs, Original Filenames, and Uploader IP Addresses

Content
View full analysis
"${output_file}.meta" << EOF { "source_url": "$url", "fetch_time": "$timestamp", "expires_at": "$((timestamp + 7 * 86400))", "mime_type": "$(file --mime-type -b "$output_file")", "file_size": $file_size, "public_url": "$public_url" } EOF ``` The upload workflow similarly stores an original filename and client IP address in the public directory: ```php $metadata = [ 'filename' => $filename, 'original_name' => $uploaded['name'], 'mime_type' => $detected_mime, 'size' => $uploaded['size'], 'upload_time' => $timestamp, 'expires_at' => $timestamp + ($config['retention_days'] * 86400), 'upload_ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown' ]; file_put_contents($filepath . '.meta', json_encode($metadata, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); ``` ### Technical Analysis Metadata files are created as `.meta` in `/var/www/media/temp/`. The nginx `/temp/` location maps requests directly to that directory and contains no rule denying `.meta` files. Anyone who knows or discovers a media URL can derive the sidecar URL by appending `.meta`. Depending on how the file was created, the response can disclose: - The original source URL - The uploader's client IP address - The original local filename supplied during upload - Upload and expiration times - Internal naming and file-size details Source URLs may contain internal hostnames, sensitive paths, query parameters, or embedded access tokens. Original filenames can reveal user or organizational information. IP addresse ...[truncated 1006 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:381
Finding

JSON Metadata Injection Through Unescaped Source URL

Content
View full analysis
"${output_file}.meta" << EOF { "source_url": "$url", "fetch_time": "$timestamp", "expires_at": "$((timestamp + 7 * 86400))", "mime_type": "$(file --mime-type -b "$output_file")", "file_size": $file_size, "public_url": "$public_url" } EOF ``` ### Technical Analysis The caller-controlled `$url` value is interpolated directly into a JSON string without JSON encoding. The scheme validation elsewhere only checks the beginning of the value and does not escape quotation marks, backslashes, control characters, or line breaks. If a crafted URL is accepted by curl and the download succeeds, special characters in the URL can make the metadata invalid or alter its logical JSON structure. For example, a quotation mark and JSON delimiters could terminate the intended `source_url` value and inject additional properties. This is data-format injection rather than shell command injection: shell metacharacters resulting from parameter expansion are not re-evaluated as shell syntax in this heredoc. The principal risk arises when another component parses, trusts, displays, indexes, or processes the manipulated metadata. ### Attack Path 1. An attacker supplies an HTTP or HTTPS URL containing JSON-significant characters. 2. The scheme-only URL check accepts the value. 3. The remote request succeeds and returns an allowed image type. 4. The raw URL is inserted into the heredoc without JSON escaping. 5. The resulting `.meta` file is malformed or contains attacker-influenced JSON structure. 6. A downstream parser, administrative interface, logging pipeline, or metadata consumer processes the manipulated content. Successful exploitation depends on the URL being accepted by curl and on a downstream component consuming the metadata. ### Impact Assessment The direc ...[truncated 375 chars]
Remediation
View remediation
"${output_file}.meta" ``` Additionally: 1. Reject control characters and impose a reasonable maximum URL length. 2. Validate the generated document before storing it. 3. Treat metadata fields as untrusted when displaying them in HTML, logs, or administrative interfaces. 4. Store metadata outside the public web root. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
echo "=== メディアホスティング初期設定 ==="
    
    # ディレクトリ作成
    sudo mkdir -p "$media_root"/{temp,uploads,processed,logs,scripts}
    
    # 権限設定
    sudo chown -R "$nginx_user:$nginx_user" "$media_root"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
echo "=== メディアホスティング初期設定 ==="
    
    # ディレクトリ作成
    sudo mkdir -p "$media_root"/{temp,uploads,processed,logs,scripts}
    
    # 権限設定
    sudo chown -R "$nginx_user:$nginx_user" "$media_root"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
echo "=== メディアホスティング初期設定 ==="
    
    # ディレクトリ作成
    sudo mkdir -p "$media_root"/{temp,uploads,processed,logs,scripts}
    
    # 権限設定
    sudo chown -R "$nginx_user:$nginx_user" "$media_root"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
76% confidence
Finding

Granting mode 775 to uploads/temp/processed makes those directories group-writable, which can be dangerous in shared-host or multi-service environments. If any other process or user shares the group, files may be modified, replaced, or planted, undermining integrity of hosted content and cleanup/processing logic.

Content

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

md
# 権限設定
    sudo chown -R "$nginx_user:$nginx_user" "$media_root"
    sudo chmod -R 755 "$media_root"
    sudo chmod 775 "$media_root"/{uploads,temp,processed}
    
    # 設定ファイル作成
    cat > "$media_root/config.env" << 'EOF'

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Granting mode 775 to uploads/temp/processed makes those directories group-writable, which can be dangerous in shared-host or multi-service environments. If any other process or user shares the group, files may be modified, replaced, or planted, undermining integrity of hosted content and cleanup/processing logic.

Content

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

md
# 権限設定
    sudo chown -R "$nginx_user:$nginx_user" "$media_root"
    sudo chmod -R 755 "$media_root"
    sudo chmod 775 "$media_root"/{uploads,temp,processed}
    
    # 設定ファイル作成
    cat > "$media_root/config.env" << 'EOF'

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
local cron_entry="0 2 * * * /var/www/media/scripts/cleanup-ephemeral-media.sh"
    
    # 現在のcrontab取得・更新
    (crontab -l 2>/dev/null; echo "$cron_entry") | sort -u | crontab -
    
    echo "cron設定完了: 毎日2時に実行"
}

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill adds an external URL fetch-and-cache feature that is outside the stated scope of temporary media hosting and introduces server-side retrieval of attacker-controlled URLs. In context, this materially increases risk because it can be used for SSRF-like access, fetching untrusted content for republication, and abuse of the host as a proxy/cache service.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Accepting arbitrary URLs and fetching them with curl enables attacker-influenced outbound network access from the server. Even though the code checks for http/https and limits size/time, it does not prevent requests to internal services, cloud metadata endpoints, or redirected destinations, making this a meaningful SSRF and network abuse risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill fetches files from third-party URLs and republishes them under a public media domain without clearly warning users in the description. This creates privacy, copyright, and trust risks because operators may unknowingly cause their server to retrieve and publicly host remote content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The upload handler logs uploader IP addresses and stores request metadata, but the skill description does not prominently disclose this privacy-relevant behavior. In a media-sharing context, silent retention of network identifiers can create compliance, consent, and user-trust issues, especially if logs are broadly accessible or retained longer than expected.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The description, headings, prompts, and user-facing strings are all written in Japanese, with no indication that language selection is optional or that the skill is intentionally limited to a Japanese-only context. Under the policy, forcing a specific language without opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.