Back to skill

Security audit

zeecu-device-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it handles precise vehicle location and silently saves the user's live API key in plaintext.

Review before installing. This skill can reveal exact vehicle location, addresses, VIN/frame identifiers, and recent trip patterns. Avoid passing the API key on the command line, run it only in a trusted workspace, and delete or protect config.json if the script has been run. Consider rotating the key if it may have been saved or synced unintentionally.

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

Warning
Location
scripts/query.py:41
Finding

API Key Is Automatically Persisted in a Plaintext Configuration File

Content
View full analysis

Vulnerability Details

File Location: scripts/query.py, lines 41–43 and 218–220
Vulnerability Type: Plaintext credential storage and unnecessary credential persistence
Risk Level: Medium

Vulnerable Code

python
def save_config_to_default(cfg: Dict[str, Any]) -> None:
    with open(CONFIG_PATH, "w", encoding="utf-8") as f:
        json.dump(cfg, f, ensure_ascii=False, indent=2)

The function is invoked unconditionally after resolving the API key:

python
# Save the resolved API Key to configuration
cfg["apiKey"] = api_key
save_config_to_default(cfg)

Technical Analysis

The script accepts the API key through three channels: the --api-key command-line argument, the API_KEY environment variable, or an existing config.json file. Regardless of the source, lines 218–220 automatically copy the resolved key into config.json.

This persistence is unnecessary when the user selected an ephemeral credential source such as an environment variable. It also contradicts the security expectation created by the README, which describes the environment variable as the recommended configuration method.

The file is created with Python's default open() behavior and therefore relies on the process umask for its permissions. The script does not explicitly enforce owner-only permissions such as mode 0600. Consequently, the credential may be exposed to other local accounts or processes depending on the runtime environment and file permissions. A plaintext file may also be collected by backup software, workspace synchronization, artifact packaging, or source-control operations.

The API key is documented as authorizing access to sensitive vehicle information, including:

  • Bound vehicle identifiers
  • TUID, frame/VIN, and barcode values
  • Exact current coordinates and street address
  • Vehicle online, power, speed, and battery status
  • Historical trip timestamps, start addresses, and destina ...[truncated 1544 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove unconditional credential persistence. Keys obtained from API_KEY or --api-key should remain in memory only for the duration of the process.
  2. Treat config.json as an explicit input rather than automatically creating or modifying it during ordinary queries.
  3. If credential storage is required, add an explicit opt-in option such as --save-api-key and clearly warn the user that the key will be stored locally.
  4. Create any credential file with owner-only permissions from the outset, for example by using os.open() with mode 0o600. Verify and reject overly permissive permissions when reading an existing file.
  5. Prefer an operating-system credential store or secret-management facility instead of a plaintext JSON file.
  6. Add config.json to .gitignore and relevant packaging exclusions to reduce the likelihood of accidental publication.
  7. Avoid recommending command-line credential input because process arguments may be visible through process inspection, shell history, or execution logs.
  8. Document credential lifecycle, storage behavior, revocation instructions, and the sensitive API capabilities granted by the key.
  9. After implementing the change, advise existing users to delete plaintext config.json files created unintentionally and rotate any key that may have been exposed.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README content is presented in Chinese only, starting with the main skill description at L03, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking audience. This can violate language/locale policy when no opt-in or justification is provided.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README explicitly recommends supplying a live API key via a command-line argument (for example, --api-key sk_live_xxx). Command-line arguments are commonly exposed through shell history, process listings, logging, and monitoring tools, which can leak credentials to other local users or operational systems. In this skill’s context, the key grants access to vehicle and user-associated device data, so credential exposure can lead to unauthorized querying of sensitive telemetry.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documents use of environment variables, local config files, and networked API calls, but it does not declare any explicit tool permissions or allowed-tools scope. This weakens sandboxing and review controls, increasing the chance that the skill can access files, secrets, or network resources beyond what users and the platform expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill handles highly sensitive data, including precise vehicle location, home/work-adjacent addresses, and ride-history records, but it does not present a clear privacy warning or consent prompt before collecting and displaying that information. This can lead to inadvertent disclosure of sensitive movement patterns and personal whereabouts, especially in shared-agent or logged environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest description is written entirely in Chinese and presents the skill as a Chinese-language capability, but there is no indication that language choice is optional or that the skill is restricted to a justified Chinese-only context. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The API returns highly sensitive telemetry including precise location, address, VIN/frame number, and trip history, but the documentation provides no warning about sensitivity, minimization, retention, or consent requirements. In this skill context, omission of such guidance increases the likelihood that implementers will over-collect, expose, or retain data that can be used to track a person's movements.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/api-spec.md (reported line 199)May include surrounding context.

md
# Operation-Type
OP_TYPE_LIST = "com.alipay.ekytsaas.skill.device.list"
OP_TYPE_QUERY = "com.alipay.ekytsaas.skill.device.query"
OP_TYPE_TRIP_LIST = "com.alipay.ekytsaas.skill.device.tripList"

# 轨迹查询约束
MAX_QUERY_DAYS = 30

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/api-spec.md (reported line 209)May include surrounding context.

md
# Operation-Type
OP_TYPE_LIST = "com.alipay.ekytsaas.skill.device.list"
OP_TYPE_QUERY = "com.alipay.ekytsaas.skill.device.query"
OP_TYPE_TRIP_LIST = "com.alipay.ekytsaas.skill.device.tripList"

# 轨迹查询约束
MAX_QUERY_DAYS = 30

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/query.py (reported line 21)May include surrounding context.

python
# Operation-Type
OP_TYPE_LIST = "com.alipay.ekytsaas.skill.device.list"
OP_TYPE_QUERY = "com.alipay.ekytsaas.skill.device.query"
OP_TYPE_TRIP_LIST = "com.alipay.ekytsaas.skill.device.tripList"

# 轨迹查询约束
MAX_QUERY_DAYS = 30

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code reads an API key from the environment or config and later persists the resolved key to config.json, silently converting a transient secret into a durable plaintext secret. This undermines the safer operational model of environment-based secret handling and can expose credentials to anyone with filesystem access or through source-control mistakes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script sends the API key, device identifier, and requests for real-time location and historical trip data to a remote endpoint. Although network access is core to the tool's purpose, the file provides no explicit user-facing warning that sensitive vehicle location/history data will be queried and transmitted.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script persists the resolved API key into ../config.json on every run, including keys sourced from command-line arguments or environment variables. Storing credentials in plaintext on disk expands the attack surface to local users, backups, logs, and accidental commits, and is not necessary for a vehicle-query tool to function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script saves the API key locally without any disclosure, consent, or confirmation to the user. Silent credential persistence is dangerous because users may reasonably assume a one-time query tool will not retain authentication material after execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language instructions, triggers, and user-facing reply templates are entirely in Chinese, which effectively forces a specific language for use of the skill. There is no indication that this is optional, user-selected, or intentionally limited to a Chinese-only audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file presents all natural-language instructions and descriptions exclusively in Chinese. Under the stated policy, forcing a specific language without user opt-in or a documented justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The spec explicitly allows storing a live API key in local config.json, creating a durable secret-at-rest that is easy to leak through source control, backups, logs, or local compromise. Because this skill accesses vehicle identity, live location, and trip-history data, exposure of the key could enable unauthorized surveillance of a user's vehicles.

Content

No source excerpt is available for this finding.