Back to skill

Security audit

MediaSync-Claw

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed remote media-sharing server, but it automatically exposes local videos over a public unauthenticated tunnel.

Install only if you intentionally want a public remote media server and can isolate it. Put only non-sensitive MP4 files in its videos folder, run it in a VM or dedicated low-privilege account, and avoid relying on the generated public hostname or MD5 checksum as access control. The current artifact should be reviewed before normal use because it has no authentication, uses plaintext public routing, and starts the tunnel automatically.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
media_server_flask.py:35
Finding
Public Unauthenticated Media Enumeration and Download<![CDATA[ ## Vulnerability Details **File Location**: `media_server_flask.py:35, 45-77, 90-178, 406-423`; `media_frp_util.py:180-194` **Vulnerability Type**: Missing authentication and automatic public service exposure **Risk Level**: High ### Vulnerable Code ```python app = Flask(__name__, template_folder='templates') socketio = SocketIO(app) ``` ```python @app.route('/api/list_files', methods=['POST']) def handle_api_list_files(): """WhatsApp API endpoint — returns a playlist of WebRTC player URLs.""" try: frp_domain = get_domain() media_files = get_media_files() if isinstance(media_files, list) and len(media_files) > 0: for media_file in media_files: media_file_name = os.path.basename(media_file) media_file_url = f"http://{frp_domain}/{media_file_name}" ``` ```python @socketio.on('connect') def handle_connect(): sid = request.sid pc = RTCPeerConnection(configuration) with pc_lock: peer_connections[sid] = pc @pc.on("datachannel") def on_datachannel(channel): @channel.on("message") def on_message(message): if isinstance(message, str) and message.startswith("request:"): filename = os.path.basename(message.split(":", 1)[1]) media_dir = os.path.realpath(get_media_directory()) filepath = os.path.realpath(os.path.join(media_dir, filename)) if not filename or not filepath.startswith(media_dir + os.sep): channel.send(json.dumps({"error": "forbidden"})) return if not os.path.isfile(filepath): channel.send(json.dumps({"error": "file not found"})) return async def stream_file_async(): async with aiofiles.open(filepath, "rb") as f: while True: chunk = await f.read(16 * 1024) ...[truncated 2312 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require authentication for every HTTP route and Socket.IO connection. 2. Generate short-lived, cryptographically random, file-scoped capability tokens. 3. Validate authorization again when processing each data-channel file request. 4. Reject Socket.IO connections that do not present a valid authenticated session. 5. Make public FRP tunneling disabled by default and require explicit user opt-in. 6. Bind the service to `127.0.0.1` unless LAN exposure is explicitly enabled. 7. Add per-client request, connection, bandwidth, and concurrency limits. 8. Expire public links and support immediate token revocation. 9. Do not treat the generated UUID hostname or an MD5 checksum as authentication. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
media_frp_util.py:180
Finding
Plaintext Public Tunnel Exposes Media Metadata and Signaling Traffic<![CDATA[ ## Vulnerability Details **File Location**: `media_frp_util.py:180-194`; `media_server_flask.py:64-69`; `templates/player.html:269-272`; `README.md:48-51` **Vulnerability Type**: Plaintext transmission of sensitive media metadata and control traffic **Risk Level**: High ### Vulnerable Code ```python frp_config_content = f''' serverAddr = "129.213.174.213" serverPort = 7000 webServer.addr = "127.0.0.1" webServer.port = 7400 [transport] heartbeatInterval = 30 heartbeatTimeout = 90 tcpMux = true tcpMuxKeepaliveInterval = 30 [[proxies]] name = "{frp_domain}" type = "http" customDomains = ["{frp_domain}"] localPort = {port} ''' ``` ```python media_file_name = os.path.basename(media_file) media_file_url = f"http://{frp_domain}/{media_file_name}" media_file_url_with_query = "videourl=" + media_file_url ``` ```javascript // Fallback: if P2P fails (symmetric NAT), use HTTP via FRPS function fallbackToHTTP() { video.src = '/' + FILENAME; progress.style.display = 'none'; } ``` The primary README makes the following inconsistent claim: ```text HTTP is strictly used for transmitting lightweight control instructions and never carries sensitive personal user data. ``` ### Technical Analysis The reverse proxy is explicitly configured with `type = "http"`, and generated media URLs use the `http://` scheme. No application-layer TLS or authenticated encryption is configured. API responses expose filenames, while Socket.IO carries WebRTC negotiation and control data through the same public service. The current Flask application does not implement a direct `/<filename>` media route, so the player's HTTP fallback appears nonfunctional in the audited version. This does not eliminate the confirmed exposure of filenames, requests, signaling metadata, and service identifiers. It also makes the README's statement that HTTP never carries sensitive personal data inaccurate. The third-party FRP relay opera ...[truncated 1186 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require HTTPS and WSS with valid certificate verification for all public traffic. 2. Use end-to-end encryption rather than relying only on optional relay-side TLS termination. 3. Remove plaintext HTTP media URLs and disable insecure fallback behavior. 4. Combine transport encryption with authentication; TLS alone does not prevent unauthorized access. 5. Correct the README to identify all metadata and content that may traverse third-party infrastructure. 6. Provide users with the relay operator, destination, purpose, and data-retention implications before enabling the tunnel. 7. Offer a local-only or user-managed VPN mode that does not depend on a public plaintext relay. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
media_server_flask.py:64
Finding
Public Hostname and Media Filenames Are Disclosed to an External Player Service<![CDATA[ ## Vulnerability Details **File Location**: `media_server_flask.py:64-70` **Vulnerability Type**: External disclosure of sensitive media identifiers **Risk Level**: Medium ### Vulnerable Code ```python for media_file in media_files: media_file_name = os.path.basename(media_file) # WebRTC player URL — browser opens this to start P2P streaming media_file_url = f"http://{frp_domain}/{media_file_name}" media_file_url_with_query = "videourl=" + media_file_url media_file_url_with_cs = f"&cks={generate_md5_checksum(media_file_url_with_query)}" aiplayer_url = f"https://yun-hub.chat/link/?app=aipollo&clickid=12345&dplink={quote(media_file_url_with_query + media_file_url_with_cs, safe='')}" txt += f"{media_file_name}: {aiplayer_url}\n" ``` ### Technical Analysis Every generated AIpollo link embeds the stable public FRP hostname and local media filename inside a query parameter sent to `yun-hub.chat` when the link is opened. These values may be recorded in server logs, analytics systems, browser history, and intermediary telemetry. The associated MD5 value is an unkeyed checksum. It provides neither confidentiality nor authentication because any party can recalculate it after changing the URL. Although use of AIpollo is advertised in the README, the precise metadata disclosure and its security consequences are not adequately controlled. The disclosure is especially significant because the media service has no authentication. The external service receives sufficient addressing and filename information to attempt direct access to the corresponding file. ### Attack Path 1. The local API enumerates a file such as `private-event.mp4`. 2. It creates a URL containing both `private-event.mp4` and the user's public `*.yunfrp.net` hostname. 3. The user opens the generated `https://yun-hub.chat/link/...` URL. 4. The complete query string is transmitted to and potentially logged by `yun-hub.chat`. 5. The external service or anyone obtainin ...[truncated 625 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Serve the player locally instead of passing media identifiers through an external link service. 2. Obtain explicit informed consent before transmitting any media metadata to a third party. 3. Replace filenames and stable hostnames with opaque, single-use identifiers. 4. Use short-lived, file-scoped capability URLs that expire after a brief period. 5. If integrity protection is needed, replace MD5 with an HMAC using a server-held secret and include an expiry time. 6. Prevent third-party links from working unless the requesting user is independently authenticated. 7. Document the external recipient, transmitted fields, purpose, and expected retention. ]]>

T08 · Insecure Dependencies

Warning
Location
media_frp_util.py:90
Finding
Automatic Download and Execution of a Third-Party Native Binary<![CDATA[ ## Vulnerability Details **File Location**: `media_frp_util.py:12-29, 90-164, 216-231, 252-255` **Vulnerability Type**: Native dependency retrieval and automatic execution **Risk Level**: Medium ### Vulnerable Code ```python FRP_VERSION = "0.65.0" FRP_CHECKSUMS = { "windows_amd64": { "archive": "5885bff09604e719e429698f800f89379f3910f07490ca1f7d8a7f7a40970eda", "binary": "5b0846d4a5e9bcde0960b354fd819eb0011529ff23f41ad55a8717ba5c7004ac", }, "darwin_amd64": { "archive": "83dcf7617c61bef0087cb771e99fd16d749203c16dd6bbf47efb15ce617dc471", "binary": "1cdbf2589fd2924d2d387d5350c6a4b4f5cecae2c6dbc594691e78dcc5fa52c7", }, "darwin_arm64": { "archive": "bce3badaf40cf5d3811c9eae593f3b24833bf7cb13b8b7c3f9453e94af45ded1", "binary": "c52b7f0d66b49a9da5d00de864aa3dfcdfd6ff214c9b5f8d72d019d1a4ae48d2", } } ``` ```python frp_url = f"https://github.com/fatedier/frp/releases/download/v{FRP_VERSION}/{archive_name}" r = requests.get(frp_url, timeout=120) r.raise_for_status() archive_data = r.content archive_hash = hashlib.sha256(archive_data).hexdigest() if archive_hash != checksums["archive"]: return False binary_hash = hashlib.sha256(binary_data).hexdigest() if binary_hash != checksums["binary"]: return False with open(frpc_path, "wb") as f: f.write(binary_data) if not plat.startswith("windows"): current_perms = os.stat(frpc_path).st_mode os.chmod(frpc_path, current_perms | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) ``` ```python frp_process = subprocess.Popen( [frpc_path, '-c', resolved_config], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) ``` ```python def setup_frp(port=8000, stop_event=None): if not download_frp(): print("Error: Failed to download frpc") return import threading frp_thread = threading.Thread( target=setup_frp_and_keep_alive, args=(port, None, stop_event), daemon= ...[truncated 2072 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit installation and first-run consent before downloading or executing FRP. 2. Retain the existing archive and executable SHA-256 verification. 3. Verify an upstream cryptographic signature against a pinned publisher key. 4. Prefer reproducible builds and publish verifiable build provenance. 5. Vendor and independently review the exact executable where licensing permits. 6. Display the download origin, version, hash, destination, and requested permissions before execution. 7. Do not instruct users to create broad antivirus exclusions. 8. Run FRP under a dedicated low-privilege account or sandbox with minimal filesystem access. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Python Packages and Runtime CDN Script Reduce Supply-Chain Integrity<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-6`; `templates/player.html:7-8` **Vulnerability Type**: Unpinned and unverified third-party dependencies **Risk Level**: Medium ### Vulnerable Code ```text flask>=3.1.3 requests>=2.32.4 jinja2>=3.1.6 aiortc aiofiles flask-socketio ``` ```html <!-- Socket.IO client — matches the Flask-SocketIO server version --> <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script> ``` ### Technical Analysis Three Python dependencies have no version constraints, while the remaining constraints permit any later version. The repository contains no lock file or cryptographic package hashes. Consequently, a future installation may execute dependency versions different from those reviewed during this audit. The player also loads executable JavaScript from a third-party CDN at runtime. Although the URL includes a version number, no Subresource Integrity value is supplied. Compromise of the CDN response or control over that versioned resource could result in browser-side code execution in the media application's origin. No typosquatted package names or known malicious dependencies were identified from the repository contents. The confirmed weakness is the absence of reproducible, cryptographically verified dependency resolution. ### Attack Path 1. A user installs the Python requirements or opens the player page. 2. The package index or CDN supplies the artifact currently resolved by the declaration. 3. Because exact package hashes or browser SRI validation are absent, the supplied code is accepted. 4. A compromised dependency executes with the Python process's privileges, or a compromised CDN script executes in the browser under the media service's origin. 5. Such code could observe media activity, alter requests, access future authentication tokens, or transmit browser-visible information externally. ### Impact Assessment A compromised Python dependency could execute code with the privil ...[truncated 373 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every Python package to an exact reviewed version. 2. Generate and commit a lock file containing cryptographic hashes. 3. Install dependencies with hash enforcement, such as `pip --require-hashes`. 4. Review and test dependency updates before changing locked versions. 5. Self-host the Socket.IO client or add a verified `integrity` attribute and appropriate `crossorigin` policy. 6. Add a restrictive Content Security Policy limiting script and connection origins. 7. Use automated dependency vulnerability and provenance scanning in the release process. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
There is a strong mismatch between the declared description and the supplied code. The description portrays a network-facing tunneling and remote-access tool that downloads and runs a third-party binary and exposes local resources externally. The actual code is a simple local utility for listing .mp4 files from a nearby 'videos' folder. It does not download anything, execute subprocesses, open ports, connect to external services, establish tunnels, or perform signaling/streaming. Its primary purpose is materially different from the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The description is only partially accurate. The code clearly does download and execute frpc, establish an outbound FRP tunnel, and expose a local HTTP service on port 8000 via a yunfrp.net domain. However, the declared purpose additionally claims outbound WebSocket/WebRTC signaling, STUN connectivity, peer-to-peer media streaming, and remote file access behavior. None of those capabilities appear in this code chunk. The actual code is limited to FRP binary retrieval, integrity verification, config generation, and process supervision for a reverse proxy tunnel. Therefore the description materially overstates the implemented behavior, creating a description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description claims substantial networking and process-execution behavior, including downloading and running frpc, exposing services to the internet, and establishing WebRTC/STUN connections. The actual code chunk does none of this. It only reads/writes a local INI file and generates a UUID when missing. This is a materially different primary purpose and capability set from the declaration, so it should be flagged as a mismatch.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding
The skill uses 'shell' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Missing User Warnings

High
Confidence
99% confidence
Finding
This code downloads, verifies, executes, and persistently maintains FRP to expose local port 8000 through a remote reverse tunnel, effectively bypassing normal network boundaries. In the context of this skill, which explicitly advertises public internet exposure and remote file access, this behavior creates a serious unauthorized access channel and materially increases the risk of data exfiltration and remote compromise.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger description allows vague natural-language requests like viewing, listing, searching, or playing local media from WhatsApp without defining strict activation boundaries, authorization checks, or scope limits. In this skill's context, that ambiguity is especially dangerous because the skill also exposes local files and network services through a reverse tunnel and P2P connectivity, so an over-broad trigger can unintentionally grant remote access to sensitive local content or actions.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The README explicitly guarantees that a third-party executable downloaded from GitHub is 'absolutely safe' and instructs users to whitelist it in security software. That is a dangerous trust claim because it downplays real supply-chain and remote-execution risk from an externally sourced binary that opens outbound tunnels and runs with local permissions.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The document claims that only HTTP control commands are transmitted and that no sensitive user data is sent, but the skill's described behavior exposes local media and remote access via public tunnels and P2P connectivity. This minimizes the confidentiality and access risks, which can mislead users into deploying an internet-exposed service without understanding that media content, metadata, and potentially internal network reachability are involved.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The README instructs users to trust and whitelist frpc.exe while asserting it is safe and untampered, even though the skill downloads and executes a third-party binary from GitHub. That assurance is unverifiable from documentation alone and can lead users to disable defenses for a network-facing executable that creates reverse tunnels, substantially increasing supply-chain and remote access risk.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The documented WhatsApp trigger phrases are natural-language requests that overlap with ordinary conversation, making skill invocation conditions ambiguous. In a skill that can enumerate media and facilitate remote access over public tunnels, accidental or spoofed activation increases the chance of unintended exposure or actions.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The README claims HTTP only carries lightweight control commands and no sensitive user information, but the same skill exposes local services publicly and supports remote file/media access. This downplays the real exposure: control channels, metadata, file names, access tokens, and service behavior can all be sensitive, and misleading assurances may cause operators to underestimate network risk.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The README states that frpc.exe is 'absolutely safe and untampered' and instructs users to whitelist it in security software, despite the skill downloading and executing a third-party binary from the internet. Absolute safety claims around executable supply chain components are unsafe because they discourage verification and defensive controls, making compromise or trojanized binary delivery more damaging.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger description is broad enough that ordinary WhatsApp messages about viewing, listing, searching, or playing local videos could activate the skill unexpectedly. In this skill's context, accidental activation is more dangerous because activation can expose local media metadata and interact with a service that establishes external connectivity and remote access paths.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The README markets the returned playback URL as a 'secure link' while elsewhere documenting public internet exposure via yunfrp.net and plaintext HTTP control traffic. This can mislead users into overtrusting the link and underestimating the exposure of local services, increasing the chance they deploy it on sensitive machines or share links unsafely.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The action trigger description is broad enough to activate on ordinary conversation, which can cause the agent to invoke local file-listing functionality without clear user intent. In this skill's context, that is more dangerous because the tool is tied to media enumeration and a service that may be remotely exposed, increasing the chance of unintended data disclosure.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The skill explicitly relies on fuzzy LLM intent matching without specific trigger constraints, creating a real risk of over-invocation and unintended tool execution. Because this skill can enumerate files and is paired with public network exposure, ambiguous prompts could result in accidental disclosure of local media resources or links to externally reachable content.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
**This materially expands your attack surface.** Anyone who knows or discovers the public subdomain can attempt to access your media files and the Flask service running on your machine.

### 1. Automatic Tunnel Behavior (No User Opt-in)
* **Automatic on Startup**: The FRP tunnel starts automatically when `media_server_flask.py` runs. There is no prompt, no confirmation, and no environment-variable gate.
* **Binary Download**: On first run, the `frpc` binary (Windows: `frpc.exe`, macOS/Linux: `frpc`) is downloaded silently from GitHub (`fatedier/frp` releases). Internet access is required.
* **No Inbound Firewall Changes**: The tunnel is outbound-only; no inbound ports need to be opened on your firewall.
Confidence
98% confidence
Finding
The skill automatically downloads and executes a third-party binary and opens a reverse tunnel to expose a local service to the public internet without any user opt-in. That combination materially increases attack surface and can lead to unauthorized remote access, data exposure, and code-execution risk through external infrastructure and downloaded native binaries.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The code silently generates an FRP configuration that points to a hard-coded external server and assigns a public yunfrp.net domain for tunneling local traffic. Auto-writing such a config without explicit warning or confirmation enables covert exposure of local services and files, which is especially dangerous given the skill's remote access and internet permissions.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if not os.path.isfile(resolved_config):
            raise FileNotFoundError(f"FRP config not found: {resolved_config}")

        frp_process = subprocess.Popen(
            [frpc_path, '-c', resolved_config],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
Confidence
95% confidence
Finding
This subprocess execution launches a downloaded third-party binary that establishes a reverse tunnel to an external server, exposing a local service to the public internet. Although shell=False avoids shell injection, the security risk is the execution of network-facing tunnel software with broad permissions and no explicit user consent or trust boundary enforcement.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if poll_result is not None:
                if stop_event and stop_event.is_set():
                    break
                frp_process = subprocess.Popen(
                    [frpc_path, '-c', resolved_config],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
Confidence
95% confidence
Finding
This restart logic persistently respawns the FRP client, maintaining continuous outbound connectivity and public exposure of a local port. The persistence increases risk by making the tunnel resilient and harder for a user to notice or stop, especially in a skill whose stated purpose includes remote file access.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
This code exposes an unauthenticated POST endpoint that enumerates local media files and constructs public links that route access through FRP and WebRTC. In the context of a skill whose stated behavior includes establishing a reverse tunnel and exposing local files to the public internet, this creates a direct unauthorized data exposure risk and substantially broadens remote access beyond a narrowly scoped media-streaming feature.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The route is misleadingly documented as a WhatsApp API endpoint, but it actually enumerates local media files and returns publicly reachable FRP/WebRTC access links for them. Mislabeling security-sensitive functionality reduces operator awareness and can conceal the fact that local files are being exposed over an internet-accessible tunnel, increasing the chance of unintended data disclosure.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The server streams file contents over WebRTC data channels to connected clients without any authentication, authorization, or user-facing disclosure at the moment data leaves the machine. In this skill’s context—public tunneling plus peer-to-peer transfer—this means local file contents can be remotely exfiltrated with minimal visibility to the user or operator.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code sets up an FRP tunnel without any user-facing warning, confirmation, or runtime disclosure at the point where outbound exposure is enabled. Given the skill metadata explicitly states that it downloads and executes a third-party tunneling binary and exposes local services on public subdomains, lack of informed consent materially increases the risk of covert remote exposure of local resources.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
This page automatically initiates WebRTC signaling, contacts multiple external STUN servers, opens a peer-to-peer data channel, and requests a file without any meaningful user notice or consent. In the broader skill context, which already exposes local resources via reverse tunneling and remote file access, the silent networking behavior materially increases the risk of covert data exposure and unexpected external connectivity.

Static analysis

No suspicious patterns detected.