Back to skill

Security audit

jf-open-pro-device-status

Security checks for vulnerabilities and agentic risk

Overview

The skill’s device-status purpose is mostly coherent, but it can send device tokens and signed account metadata to any hostname supplied through JF_ENDPOINT.

Install only if you trust the publisher and can control the runtime environment. Do not let untrusted users, CI inputs, wrappers, or generated configs set JF_ENDPOINT; restrict it to the documented JFTech API hosts. Treat device tokens, UUID, app key, app secret, signatures, and WAN IPs as sensitive, and avoid table output if WAN IP disclosure is not needed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/device_status.py:26
Finding

Unrestricted API Endpoint Allows Redirection of Device Tokens and Authentication Metadata

Content
View full analysis

Vulnerability Details

File Location: scripts/device_status.py, lines 26–27 and 49–57
Vulnerability Type: Unvalidated destination for sensitive outbound requests
Risk Level: High

Vulnerable Code

python
# API base address (switchable through an environment variable)
JF_ENDPOINT = os.getenv("JF_ENDPOINT", "api-cn.jftechws.com")
JF_BASE_URL = f"https://{JF_ENDPOINT}/gwp/v3"
python
url = f"{JF_BASE_URL}/rtc/device/status"
headers = get_headers(uuid, app_key, app_secret, move_card)

body = {
    "deviceTokenList": device_tokens,
    "region": region
}

response = requests.post(url, headers=headers, json=body, timeout=30)

Technical Analysis

The destination hostname is read directly from the JF_ENDPOINT environment variable and interpolated into the request URL without validation or an allowlist. Consequently, the request can be redirected to any HTTPS server rather than being restricted to the four regional API domains documented by the Skill.

Each redirected request contains sensitive information:

  • Device access tokens in deviceTokenList
  • The platform account UUID
  • The application key
  • A timestamp
  • A signature derived from the application secret
  • A request identifier

The application secret itself is not transmitted directly. Nevertheless, device tokens and account authentication metadata are disclosed to the selected destination. The documentation states that device tokens remain valid for 24 hours.

Allowing arbitrary destinations exceeds the minimum privileges required for device-status queries. The declared functionality only needs access to the documented JFTech regional API hosts:

  • api-cn.jftechws.com
  • api-as.jftechws.com
  • api-eu.jftechws.com
  • api-na.jftechws.com

TLS does not mitigate this issue because the program intentionally establishes TLS with the attacker-selected hostname. A valid certificate for that hostname is suffi ...[truncated 1750 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the free-form hostname with a fixed region-to-endpoint mapping:

    python
    ENDPOINTS = {
        "CN": "api-cn.jftechws.com",
        "AS": "api-as.jftechws.com",
        "EU": "api-eu.jftechws.com",
        "NA": "api-na.jftechws.com",
    }
    
    selected_region = os.getenv("JF_REGION", "CN")
    if selected_region not in ENDPOINTS:
        raise ValueError("Unsupported API region")
    
    JF_BASE_URL = f"https://{ENDPOINTS[selected_region]}/gwp/v3"
    
  2. If backward compatibility requires JF_ENDPOINT, validate it against an exact hostname allowlist before constructing the URL:

    python
    ALLOWED_ENDPOINTS = {
        "api-cn.jftechws.com",
        "api-as.jftechws.com",
        "api-eu.jftechws.com",
        "api-na.jftechws.com",
    }
    
    endpoint = os.getenv("JF_ENDPOINT", "api-cn.jftechws.com")
    if endpoint not in ALLOWED_ENDPOINTS:
        raise ValueError("JF_ENDPOINT is not an approved API endpoint")
    
  3. Reject endpoint values containing schemes, user information, ports, paths, query strings, fragments, trailing dots, wildcard subdomains, or IP literals. Exact string matching against canonical hostnames is preferable.

  4. Keep TLS certificate verification enabled and do not add an option that disables verification.

  5. Minimize token exposure by sending only tokens needed for the requested operation and clearing unnecessary in-memory collections after batch processing where practical.

  6. Treat endpoint configuration as security-sensitive. Prevent untrusted users, workflow inputs, or generated configuration from controlling the Skill's process environment.

  7. Rotate potentially exposed device tokens and application credentials if the Skill has previously run with an untrusted JF_ENDPOINT.

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

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

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The request destination is derived from the JF_ENDPOINT environment variable and then used to construct the HTTPS URL for requests.post. Because the same request includes device tokens plus authentication headers (uuid, appKey, signature, timeMillis), a malicious or misconfigured environment can redirect sensitive data to an attacker-controlled host, causing credential and device-identifier exfiltration.

Content

Scanner excerpt · scripts/device_status.py (reported line 61)May include surrounding context.

python
"region": region
    }
    
    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
98% confidence
Finding

声明的核心能力是查询设备在线状态,但提供的代码片段仅是一个加密签名辅助模块,用于构造 OpenAPI 请求签名。它没有网络请求、没有设备标识查询逻辑、没有单设备或批量处理流程、没有解析设备状态返回值,因此其主要用途与声明明显不一致。这属于主功能 materially different primary purpose 的情况,应判定为描述与行为不匹配。

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 166)May include surrounding context.

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

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill documentation declares environment variables, file-based token input, and outbound API usage, but it does not define any explicit tool scope such as allowed tools or permissions. In an agent environment, missing scope boundaries can allow broader-than-expected access to env, filesystem, and network resources, increasing the risk of unintended data exposure or misuse.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger phrase '查询设备状态' is broad enough to match requests about device health, telemetry, configuration, or control state, while the skill only intends to answer online/offline status. Overbroad activation can cause the wrong skill to run, potentially exposing device identifiers or network-related data such as WAN IP when the user did not intend that workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation states that responses include the device's external WAN IP but does not classify it as sensitive or warn against unnecessary disclosure. External IP data can reveal network location, infrastructure details, and targeting information, especially when combined with device identity and online status.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language description and all user-facing text in this file are presented only in Chinese, indicating an implicit fixed language choice. The policy requires avoiding forced language or locale behavior unless the skill offers opt-in choice or clearly documents a justified region-specific constraint.

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/device_status.py (reported line 61)May include surrounding context.

python
"region": region
    }
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code sends device tokens and signed authentication headers to a remote API via an HTTP POST request, which transmits user/system data off the local machine. While the function docstring describes the API call technically, there is no explicit user-facing warning, confirmation, or disclosure near the operation about external data transmission or the use of credentials.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill claims to focus on online/offline status, but the table output also reveals each device's WAN IP address. This expands data exposure beyond the stated purpose and can disclose network-location information that may aid reconnaissance or violate user expectations about the minimality of returned data.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The skill lists several trigger phrases but does not document boundaries or non-matching examples. Without explicit scope constraints, nearby everyday phrasing may activate the skill when the user intended a different kind of device inquiry.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

SQP-3 applies to all file types and includes language or locale policy violations. This module's user-facing documentation and comments are Chinese-only, and the file does not indicate that the skill is region-specific or provide an opt-in language choice.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This skill is described as a device online-status query tool, but it also pulls runtime configuration and secrets from environment variables, including JF_ENDPOINT, JF_UUID, JF_APP_KEY, and JF_APP_SECRET. While common operationally, this credential/configuration access is not reflected in the stated scope and is not intrinsic to the user-facing purpose described in the manifest.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script reads UUID, app key, and app secret from command-line arguments or environment variables, including the sensitive secret value. Although these values are required for the tool's purpose, the file does not include any explicit warning or user-facing disclosure about handling credentials from the environment.

Content

No source excerpt is available for this finding.