Back to skill

Security audit

jf-open-pro-local-record

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its stated video-recording purpose, but it handles sensitive device credentials and private surveillance URLs with an unvalidated configurable endpoint and limited safety guidance.

Review before installing. Only set JF_ENDPOINT to an official JFTech regional host, avoid exposing these environment variables in logs or chats, treat playback/download/image URLs as temporary credentials, and be careful with stream switching because it changes future recording quality. The current script also has a duplicate CLI argument bug that prevents normal execution until fixed.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

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

Critical
Category
Data Flow
Content
}
    }
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
88% confidence
Finding
The request destination is derived from the JF_ENDPOINT environment variable and then used to build authenticated HTTPS requests containing UUID, appKey, signature, and in some APIs device credentials. If an attacker can influence that environment variable, the skill can be redirected to an attacker-controlled host and exfiltrate signed requests and sensitive metadata, which is effectively SSRF plus credential leakage.

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

Critical
Category
Data Flow
Content
}
    }
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
88% confidence
Finding
This POST uses a URL ultimately controlled by JF_ENDPOINT, so a manipulated runtime environment can redirect record-list queries to an untrusted server. Because the request includes authentication headers and device-identifying data, this can leak credentials and operational information outside the intended platform.

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

Critical
Category
Data Flow
Content
"playPrioritize": play_prioritize
    }
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
95% confidence
Finding
The playback/download URL request is sent to a host derived from JF_ENDPOINT and includes especially sensitive fields such as device username and password in the JSON body. If the endpoint is overridden, the skill will transmit device credentials directly to an attacker-controlled server, enabling device compromise beyond simple data leakage.

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

Critical
Category
Data Flow
Content
"fileName": file_name
    }
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
91% confidence
Finding
Alarm image retrieval also posts to a URL built from an environment-controlled endpoint. While this call may not include the device password, it still transmits signed authentication headers and file metadata, allowing unauthorized collection of sensitive device and account information if redirected.

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

Critical
Category
Data Flow
Content
"stream": stream
    }
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
86% confidence
Finding
The stream-switch command sends authenticated control traffic to a host derived from JF_ENDPOINT. An attacker who controls that environment variable could capture auth headers or potentially cause unauthorized device-management actions against a rogue service, exposing both credentials and control intent.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documentation describes use of environment variables and outbound network access to device/cloud APIs, but the skill declares no permissions or security boundary information. This creates a transparency and governance gap: users or reviewers may approve or run the skill without understanding that it can read secrets and contact external endpoints using those secrets.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The CLI defines a second --stream-type argument with dest=playback_stream, but playback handlers still read args.stream_type from the earlier list-query option. This parameter confusion can cause the tool to ignore the user's requested playback stream and operate on an unintended stream, which is a logic flaw that can lead to incorrect media access, billing, or policy bypass in environments where stream selection matters.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation instructs users to provide highly sensitive credentials and tokens, and it discusses retrieval of playback/download URLs that grant access to private surveillance media, but it gives no warning about secret handling, log exposure, URL sharing, or privacy risks. In this context, exposed device tokens, passwords, or time-limited media URLs could allow unauthorized access to home/business recordings and alarm images.

Missing User Warnings

Low
Confidence
79% confidence
Finding
The stream-switch feature changes the quality of future recordings, which can reduce evidentiary value, forensic usefulness, or user expectations if changed unintentionally or without informed consent. In a surveillance-recording skill, silent downgrades from main stream to sub-stream can materially affect later incident review even if they do not directly expose data.

Static analysis

Detected: suspicious.env_credential_access

Python code POSTs credential environment variables to an environment-controlled URL.

Critical
Code
suspicious.env_credential_access
Location
scripts/local_record.py:73