Back to skill

Security audit

jf-open-pro-device-list

Security checks for vulnerabilities and agentic risk

Overview

This device-list skill is review-worthy because it can print device login tokens and can send signed account requests to an arbitrary endpoint set by an environment variable.

Install only if you trust the publisher and understand that routine runs may expose device login tokens or full device credential fields in logs or transcripts. Use only trusted JFTech endpoints, avoid setting JF_ENDPOINT to arbitrary hosts, and prefer a version that redacts password/loginToken by default and requires explicit opt-in for sensitive output.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/device_list.py:25
Finding

Unvalidated API endpoint allows sensitive requests to be redirected to an arbitrary host

Content
View full analysis
Dict[str, str]: """生成请求头(包含签名和时间戳)""" 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 query_device_list(uuid: str, app_key: str, app_secret: str, move_card: int, page: int = 1, limit: int = 100) -> Dict[str, Any]: """ 分页查询设备列表 API: POST /gwp/v3/rtc/device/list """ url = f"{JF_BASE_URL}/rtc/device/list" headers = get_headers(uuid, app_key, app_secret, move_card) body = { "page": page, "limit": limit } response = requests.post(url, headers=headers, json=body, timeout=30) result = response.json() if result.get("code") != 2000: raise RuntimeError(f"查询设备列表失败:{result.get('msg', '未知错误')}") return result.get("data", {}) def query_by_sns(uuid: str, app_key: str, app_secret: str, move_card: int, sns: List[str]) -> Dict[str, Any]: """ 按设备序列号查询 API: POST /gwp/v3/rtc/device/list """ url = f"{JF_BASE_URL}/rtc/device/list" headers = get_headers(uuid, app_key, app_secret, move_card) body = { "sns": sns } response = requests.post(url, headers=headers, json=body, timeout=30) ``` ### Technical Analysis The destination hostname i ...[truncated 2620 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/device_list.py:108
Finding

Device passwords and login tokens can be exposed through standard output

Content
View full analysis
28: token = token[:25] + "..." print(f"{sn:<22} {username:<12} {nickname:<20} {token:<30}") print("=" * 90) print(f"📊 总计:{len(device_list)} 个设备") print() def print_json(device_list: List[Dict[str, Any]]): """JSON 格式输出""" print(json.dumps(device_list, indent=2, ensure_ascii=False)) def print_simple(device_list: List[Dict[str, Any]]): """简洁格式输出""" if not device_list: print("⚠️ 无设备数据") return print() for i, device in enumerate(device_list, 1): sn = device.get("sn", "未知") username = device.get("username", "-") nickname = device.get("nickname", "") nickname_text = f" ({nickname})" if nickname else "" print(f"{i}. 📱 {sn}{nickname_text}") print(f" 用户名:{username}") token = device.get("loginToken", "") if token: print(f" Token: {token[:50]}...") print() print(f"📊 总计:{len(device_list)} 个设备") print() ``` ### Technical Analysis The API response schema documented in `SKILL.md` includes device `password` and `loginToken` fields. The JSON output function serializes each complete device object withou ...[truncated 2183 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 (16)

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The request destination is derived from the JF_ENDPOINT environment variable and is used to send authenticated API requests containing uuid, appKey, timestamped signature, and query data. If an attacker can influence the runtime environment, they can redirect requests to an attacker-controlled host and capture signed authentication material or sensitive device metadata; the skill context increases risk because this tool is intended to access account-bound device inventories.

Content

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

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

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

This second request path has the same issue: the URL is built from an environment-controlled endpoint and then used in a POST that includes signed authentication headers and sensitive device identifiers (SNS values). A manipulated environment can exfiltrate serial numbers and authentication-related headers to an untrusted server, which is particularly dangerous in a device-management skill handling account-linked assets.

Content

Scanner excerpt · scripts/device_list.py (reported line 84)May include surrounding context.

python
"sns": sns
    }
    
    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

The documented behavior claims device listing, pagination, and serial-number filtering, while the referenced implementation reportedly only performs signature and timestamp generation. A description/behavior mismatch is dangerous because users may authorize the skill expecting a simple read-only query, while the actual code path is opaque and could conceal undeclared behavior or fail to enforce the advertised data-handling boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly states that responses may include sensitive device credentials such as usernames, passwords, and login tokens, but it provides no clear warning, masking policy, consent step, or handling restrictions. In this context, exposing authentication material is especially dangerous because it can enable direct device access, account pivoting, and long-lived compromise if outputs are logged, shared, or shown to unintended users.

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

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

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documentation indicates use of environment variables, file input, and outbound network access, but it does not declare any tool scope such as permissions or allowed-tools. This creates a transparency and governance gap: a host may permit broader execution than users expect, and reviewers cannot easily verify least-privilege constraints before activation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases include broad everyday expressions such as '设备列表', '我的设备', and '绑定设备', which can cause accidental invocation in normal conversation. Because this skill interfaces with account-bound device data and may expose credentials or tokens, unintended triggering increases the chance of unnecessary sensitive-data retrieval and disclosure.

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

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

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_list.py (reported line 84)May include surrounding context.

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

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The output helpers expose device loginToken values in table and simple formats, and JSON output may also include full token-bearing device objects. Printing authentication tokens to stdout creates a clear risk of credential disclosure through terminal logs, shell history capture, orchestration logs, screenshots, or downstream tooling; in this skill, token exposure is more dangerous because the stated purpose is only device-list lookup, not token handling.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The table output explicitly reads and prints the loginToken field despite the skill being described as a device-list query utility. This unnecessarily broadens the data exposure surface and may leak bearer-style credentials to any user or system consuming command output, making the context materially more dangerous than a pure inventory listing tool.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script prints token data to stdout without an upfront warning or explicit consent mechanism, so sensitive authentication material can be exposed during routine usage. Even truncated tokens can still leak useful secret fragments and confirm token presence; moreover, users may switch to JSON output and expose full values if the raw device object includes them.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

In simple mode, the tool prints loginToken fragments directly in a human-readable listing, which is likely to be copied, screenshotted, or logged. Because this mode is the default output path for routine use, the skill context makes the exposure especially risky and increases the chance of accidental credential leakage.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

整个技能名称、描述、触发词和使用说明均仅以中文提供,没有说明该技能仅面向特定中文用户群体,也未提供语言选择。按照语言/区域政策,若限定单一语言,通常应有明确适用范围或用户可选项。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code file contains natural-language documentation in Chinese in the module docstring, and later prints a Chinese warning message. Under the policy for all file types, forcing a specific language without offering user choice or documenting a justified locale restriction is a language/locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The printed notice at L179 is presented only in Chinese, which imposes a specific language on users of the script. The file does not offer a language selection mechanism or state that the tool is intentionally limited to a Chinese-language environment.

Content

No source excerpt is available for this finding.