Back to skill

Security audit

jf-open-pro-livestream

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated JFTech livestream purpose, but it handles camera/device secrets and can send them to an unconstrained configured endpoint.

Review before installing. Use this only for JFTech devices and accounts you control, keep JF_APP_SECRET, JF_DEVICE_TOKEN, device passwords, and generated livestream URLs private, avoid setting JF_ENDPOINT outside documented JFTech domains, and avoid test-url on sensitive networks unless URL destination validation is added.

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
scripts/livestream.py:25
Finding

Unrestricted API Endpoint Can Expose Device and Application Credentials

Content
View full analysis
Dict[str, str]: """Generate request headers containing a signature and timestamp.""" time_millis = get_time_millis() signature = generate_signature(uuid, app_key, app_secret, time_millis, move_card) return { "Content-Type": "application/json; charset=UTF-8", "uuid": uuid, "appKey": app_key, "timeMillis": time_millis, "signature": signature, "X-Request-Id": os.urandom(16).hex() } def get_livestream_url(device_token: str, uuid: str, app_key: str, app_secret: str, move_card: int, channel: str = "0", stream: str = "1", protocol: str = "flv", username: str = "admin", password: str = "", expire_time: Optional[int] = None) -> Dict[str, Any]: """ Obtain a device livestream address. API: POST /gwp/v3/rtc/device/livestream/{deviceToken} """ url = f"{JF_BASE_URL}/rtc/device/livestream/{device_token}" headers = get_headers(uuid, app_key, app_secret, move_card) body = { "channel": channel, "stream": stream, "protocol": protocol, "username": username, "password": password } if expire_time: body["expireTime"] = str(expire_time) response = requests.post(url, headers=headers, json=body, timeout=30) ``` ### Technical Analysis The `JF_ENDPOINT` environment variable is inserted directly into the API URL without validation or an allowlist. The result ...[truncated 2282 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/livestream.py:190
Finding

Server-Controlled Livestream URL Enables SSRF and Unsafe Redirect Following

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/crypto.py:85
Finding

Zero Move-Card Value Causes Deterministic Signature Generation Failure

Content
View full analysis
((encrypt_length - i) % move_card): temp = encrypt_byte[i] else: temp = encrypt_byte[encrypt_length - (i + 1)] encrypt_byte[i] = encrypt_byte[encrypt_length - (i + 1)] encrypt_byte[encrypt_length - (i + 1)] = temp return encrypt_byte ``` The documented environment setup also recommends a value of zero: ```bash export JF_MOVE_CARD=0 ``` ### Technical Analysis The `change()` function uses `move_card` as the divisor in modulo operations. Neither the command-line parser nor the cryptographic helper verifies that the value is greater than zero. When `move_card` is zero, Python raises `ZeroDivisionError` during signature generation. The exception is not handled by the action handlers, which only catch `RuntimeError` and request-related exceptions. As a result, the process terminates before making the intended API request. The default code value is `2`, but the example in `SKILL.md` explicitly sets `JF_MOVE_CARD=0`, making the failure reproducible when users follow the documented setup. ### Attack Path 1. A user follows the environment-variable example and sets `JF_MOVE_CARD=0`, or an attacker able to influence configuration supplies zero. 2. The user invokes either supported action. 3. Header generation calls `generate_signature()`, which calls `change()`. 4. The expression `i % move_card` performs modulo by zero. 5. Python raises `ZeroDivisionError`. 6. The uncaught exception terminates the Skill, preventing livestream URL retrieval or testing. ### Impact Assessment This issue affects availability rather than confidentiality or privilege boundaries. It allows a configuration value to reliably crash the Skill for every invocation requiring signature generation. ...[truncated 191 chars]
Remediation
View remediation
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (11)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/livestream.py (reported line 72)May include surrounding context.

python
if expire_time:
        body["expireTime"] = str(expire_time)
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的核心能力是实时视频直播预览与多协议播放支持;而提供的代码块完全聚焦于签名算法和时间戳生成,是接口认证辅助工具。代码中没有任何播放器、媒体流处理、协议适配、编解码支持或设备预览相关实现。因此其实际行为与声明用途存在明显且实质性的偏离,应判定为不匹配。

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `SKILL.md` | 技能文档 |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documentation describes use of environment variables and outbound API access, but it does not declare any explicit tool scope such as allowed-tools or permissions. In an agent ecosystem, missing scope declarations can cause overbroad execution assumptions, reduce reviewability, and allow a caller to invoke networked and secret-consuming behavior without clear consent boundaries.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrases are broad and generic, such as '实时播放' and '获取播放 URL', without limiting them to JFTech devices, authorized accounts, or safe contexts. In agent routing systems, ambiguous triggers can cause this skill to activate for unrelated user requests and unnecessarily access secrets or request sensitive stream URLs.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The repeated trigger section reinforces ambiguous invocation language and still lacks guardrails about account ownership, device binding, or authorization checks. This increases the chance of unintended invocation and accidental disclosure or generation of sensitive livestream URLs in response to loosely related prompts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation includes handling of app secrets, device tokens, usernames, passwords, and generated stream URLs, but it does not prominently warn that these values are sensitive and must not be logged, shared, or exposed in chat outputs. Stream URLs and device credentials can enable unauthorized viewing or device access, especially when URLs remain valid for hours or days.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The request body includes username and password, and the code sends them via requests.post to the external livestream endpoint. While the script prints status information, it does not clearly disclose to the user that device credentials are being transmitted off-host to obtain the stream URL.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/livestream.py (reported line 72)May include surrounding context.

python
if expire_time:
        body["expireTime"] = str(expire_time)
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The test-url action performs a HEAD request to the livestream URL returned by the remote API, adding a URL probing capability beyond the core function of merely retrieving URLs. If the upstream API or configuration is compromised, this can induce the agent to connect to arbitrary URLs, enabling SSRF-style outbound requests or internal network reachability checks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The docstring and all CLI messages are written in Chinese, which imposes a specific language on users. There is no indication that the tool is region-specific or that users can opt into another language/locale.

Content

No source excerpt is available for this finding.