Back to skill

Security audit

M5Stack Firmware Query

Security checks for vulnerabilities and agentic risk

Overview

This is a read-only public firmware lookup skill, with a configurable API endpoint that users should leave on the trusted default unless intentionally testing.

Install this only if you are comfortable with firmware searches being sent to the public M5Burner service. Keep the API base URL at the default unless you intentionally control and trust another HTTPS-compatible deployment, do not provide bearer tokens or account credentials, and treat firmware descriptions, comments, and source URLs as public third-party content.

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/m5stack_firmware_query.py:107
Finding

Unrestricted API Base URL Enables Server-Side Request Forgery and Insecure HTTP Communication

Content
View full analysis
None: base_url = base_url.strip().rstrip("/") if not base_url.startswith(("http://", "https://")): raise ApiError("base URL must start with http:// or https://") self.base_url = base_url self.timeout = timeout def get( self, path: str, *, params: Mapping[str, Any] | None = None, headers: Mapping[str, str] | None = None, ) -> Any: query = urlencode(compact_params(params or {})) url = f"{self.base_url}/{path.lstrip('/')}" if query: url = f"{url}?{query}" request_headers = { "Accept": "application/json", "User-Agent": USER_AGENT, } request_headers.update(headers or {}) request = Request(url, headers=request_headers, method="GET") try: with urlopen(request, timeout=self.timeout) as response: raw = response.read() status = response.status ``` ```python parser.add_argument( "--base-url", default=DEFAULT_BASE_URL, help="Compatible M5Burner base URL (or M5BURNER_API_BASE_URL)", ) ``` ### Technical Analysis The API client validates only that the supplied base URL begins with `http://` or `https://`. It does not restrict the destination hostname, port, resolved IP address, or transport security. Consequently, either the `--base-url` argument or the `M5BURNER_API_BASE_URL` ...[truncated 3093 chars]
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs the agent to run a local Python script that can access both network resources and environment variables, but the manifest does not declare any explicit tool scope such as allowed tools, network access, or environment exposure limits. That creates an over-privilege/visibility gap: a runtime may grant broader capabilities than intended, making it harder to enforce read-only behavior or prevent accidental access to sensitive environment data or non-public endpoints.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill enables implicit invocation without any visible activation constraints, exclusions, or narrowing conditions. Even though the skill is read-only and limited to public firmware discovery, broad automatic triggering can cause the agent to invoke the skill in unintended contexts, potentially leaking user intent to an external repository query path or producing irrelevant/unexpected actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This is a code file, so SQP-3 applies to natural-language strings in the code. Several user-visible errors and status messages are emitted only in Chinese (for example at L0088, and similarly later), while the CLI does not offer a corresponding output-language opt-in, which can violate language/locale policy requiring user choice or justified locale constraints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code returns multiple user-facing messages such as "不支持的查询意图" and later success/status strings like "意图查询成功" and "聚合查询成功". Because the tool mixes English CLI help with Chinese runtime output and does not let the user choose the output language, this is a clear natural-language locale policy concern rather than a functional bug.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This test asserts that recommendation and classification text contains Chinese strings such as "音乐", "只提到项目由", and "需要配置 Gemini API Key". In a code file, these embedded expectations indicate the skill produces a fixed locale in user-facing text, but there is no evidence here of user opt-in or a documented language-selection mechanism.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The short description is in Chinese while the default prompt is in English, but the manifest does not state whether the user can choose a preferred language or whether the skill is intended for a specific locale. This may create an implicit language policy mismatch without clear user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The example response bodies use the Chinese message string "查询成功" in a general API reference, which can be read as prescribing a specific language/locale for responses. The file does not indicate that this is merely an observed production example, offer alternatives, or justify a locale-specific constraint.

Content

No source excerpt is available for this finding.