Back to skill

Security audit

西之月登录

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its Westmoon QR-login purpose, but it needs Review because it persists reusable login tokens for broad reuse and automatically opens remote-supplied QR files with weak validation.

Install only if you trust this publisher and the Westmoon API endpoint with your account session. Treat ~/.westmoon-user-login/tokens.json as a sensitive credential file, avoid letting untrusted skills read it, and prefer manual review before implicit login flows. The QR-opening behavior should ideally be changed to validate PNG data strictly and avoid automatic OS-handler opening by default.

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

Warning
Location
scripts/qr_code_client.py:52
Finding

Remote API controls the type and contents of an automatically opened file

Content
View full analysis
Tuple[bool, Optional[bytes], Optional[str]]: if not data_uri or "," not in data_uri: return False, None, None header, encoded = data_uri.split(",", 1) image_format = "png" if ";" in header and "/" in header: image_format = header.split("/")[1].split(";")[0].strip() try: return True, base64.b64decode(encoded), image_format except Exception: return False, None, image_format def save_qr_image( self, image_bytes: bytes, image_format: str = "png", output_path: Optional[str] = None ) -> Optional[str]: try: if output_path: file_path = Path(output_path) else: save_dir = Path.home() / ".westmoon-user-login" / "qr_codes" save_dir.mkdir(parents=True, exist_ok=True) file_path = save_dir / f"login_qr_{int(time.time())}.{image_format}" with file_path.open("wb") as handle: handle.write(image_bytes) return str(file_path) except Exception as exc: print(f"[QRCodeClient] 保存二维码失败: {exc}") return None def open_qr_image(self, file_path: str) -> bool: try: system = platform.system() if system == "Darwin": subprocess.run(["open", file_path], check=True) elif system == "Linux": subprocess.run(["xdg-open", file_path], check=True) elif system == "Windows": os.startfile(file_path) else: return False return True except Exception as exc: print(f"[QRCodeClient] 打开二维码失败: {exc}") return False ``` ```python # scripts/w ...[truncated 3196 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/token_manager.py:85
Finding

Reusable access and refresh tokens are stored in plaintext for cross-Skill access

Content
View full analysis
bool: if self._token_info is None: return True try: temp_file = self.token_file.with_suffix(".tmp") with temp_file.open("w", encoding="utf-8") as handle: json.dump(self._token_info.to_dict(), handle, indent=2, ensure_ascii=False) os.chmod(temp_file, 0o600) temp_file.replace(self.token_file) return True except Exception as exc: print(f"[TokenManager] 保存登录态失败: {exc}") return False ``` The documented file contains both credential types: ```json { "access_token": "xxx", "refresh_token": "xxx", "token_type": "Bearer", "expires_in": 604800, "expires_at": 1776244244.0, "created_at": 1775639444.0, "user_info": { "id": "85844", "name": "xxx" } } ``` The integration guide explicitly instructs other Skills to read the plaintext file: ```python # references/integration_guide.md:30-36 import json from pathlib import Path token_file = Path.home() / ".westmoon-user-login" / "tokens.json" data = json.loads(token_file.read_text(encoding="utf-8")) authorization = f"{data['token_type']} {data['access_token']}" ``` ### Technical Analysis The implementation writes access tokens, refresh tokens, and user information to an ordinary JSON file. The directory is set to mode `0700`, and newly written credential files are set to mode `0600`, which is a meaningful protection against other POSIX users. Those permissions do not isolate the credentials from other Skills, processes, or compromised code running under the same operating-system account. The inte ...[truncated 1868 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill advertises an immediate full login workflow, but the default behavior is non-blocking and leaves a pending login state for later continuation; it also exposes undeclared capabilities like logout, token status inspection, and user info retrieval. Such discrepancies can cause other skills or users to rely on incorrect authentication semantics, potentially exposing tokens, clearing session state unexpectedly, or creating confused-deputy behavior in downstream automation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill advertises an immediate full login workflow, but the default behavior is non-blocking and leaves a pending login state for later continuation; it also exposes undeclared capabilities like logout, token status inspection, and user info retrieval. Such discrepancies can cause other skills or users to rely on incorrect authentication semantics, potentially exposing tokens, clearing session state unexpectedly, or creating confused-deputy behavior in downstream automation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill describes capabilities that require network access, local file reads/writes, shell execution, and environment inspection, but it does not declare any tool scope or permissions boundaries. In an agent environment, this increases the chance of unintended or over-privileged execution because reviewers and orchestrators cannot constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are broad enough that the skill may auto-activate whenever another skill detects a missing or invalid token, not only when the user explicitly requests login. In an agent system, this can cause unexpected authentication flows, unsolicited QR generation, unnecessary network calls, and unintended persistence of credentials on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly stores access_token, refresh_token, and user information in a predictable file under the user's home directory, but it provides no warning about sensitivity, retention, file permissions, or local compromise risk. Persistent bearer and refresh tokens are high-value secrets; if another local process, user, or misconfigured backup/logging system accesses them, an attacker may be able to hijack the Westmoon account for an extended period.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly stores access_token, refresh_token, and user information in a predictable file under the user's home directory, but the documentation provides no warning about credential sensitivity, file permissions, or local compromise risk. This can expose reusable authentication secrets to other local users, malware, backups, logs, or accidental sharing, especially because refresh tokens enable longer-lived account access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The guide instructs other skills to read reusable access and refresh tokens directly from a predictable file in the user's home directory and shows how to construct authorization headers from that file, but it provides no warnings about credential sensitivity, file permissions, or trust boundaries between skills. In this skill ecosystem, any other local skill or process that can read the file may silently reuse or exfiltrate long-lived tokens, expanding compromise from a single skill to the entire Westmoon account.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

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

python
try:
            system = platform.system()
            if system == "Darwin":
                subprocess.run(["open", file_path], check=True)
            elif system == "Linux":
                subprocess.run(["xdg-open", file_path], check=True)
            elif system == "Windows":

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/qr_code_client.py (reported line 86)May include surrounding context.

python
if system == "Darwin":
                subprocess.run(["open", file_path], check=True)
            elif system == "Linux":
                subprocess.run(["xdg-open", file_path], check=True)
            elif system == "Windows":
                os.startfile(file_path)
            else:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code performs network requests containing a login scan token and processes access and refresh tokens from the response, which are privacy- and security-relevant operations. Although the module docstring mentions polling helpers, there is no confirmation prompt, user-facing log/print, or explicit warning comment/docstring disclosing that authentication-related tokens are sent and received over HTTP.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code hard-codes a Chinese locale string ("未知") for token expiry display, which imposes a specific language choice on users. The file also includes additional Chinese user-facing messages elsewhere, with no opt-in or documented locale constraint, which matches the language/locale policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The printed status and error messages in this file are presented only in Chinese, such as load/save failure messages, without offering users a language choice. For a general-purpose token manager, this is a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code prints the raw scan_token and, in OPENCLAW_SESSION mode, emits the full qr_data_uri to stdout. Anyone with access to console logs, transcript capture, CI artifacts, terminal multiplexers, or agent message history may obtain the live QR login artifact and hijack or interfere with the authentication flow before it expires.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a skill that should trigger QR login, display the QR code, poll scan status, and save tokens for reuse. The CLI also implements status inspection, token validity checking, user-info retrieval, and logout operations via --status, --check, --userinfo, and --logout, which go beyond the stated login workflow.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest focuses on acquiring and refreshing Westmoon login state and saving tokens for reuse by other skills. Removing tokens and pending login state is a separate account-state management capability that is not described as part of this skill's purpose.

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 the skill name and description in Chinese while the default invocation prompt is fixed in English. This creates a language-policy concern because the skill appears to impose language behavior without any documented user opt-in or locale-selection mechanism.

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 content, including headings and operational guidance, is presented only in Chinese, and there is no note offering an alternative language or clarifying that the skill is intended for a Chinese-speaking audience only. Under the stated policy, forcing a specific language without opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

A skill document that forces a single language without user opt-in can violate language or locale policy. This file provides all operational instructions only in Chinese and does not mention any alternative language, opt-in, or region-specific justification.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency is specified as requests>=2.31.0, which allows any future version to be installed and makes builds non-reproducible. In a login-related skill that handles access tokens and user identity data, this increases supply-chain and patch-management risk because a vulnerable or breaking upstream release could be pulled in without review.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

Because the manifest does not pin requests to a specific version, it is impossible to verify whether the installed package includes fixes for known advisories affecting requests. This is more concerning in this skill's context because it performs QR-code login flows, polls remote endpoints, and stores tokens, so HTTP client weaknesses could contribute to credential leakage, improper TLS behavior, or other security issues affecting authentication data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This Python file contains user-visible print messages in Chinese only (for save/open failures), which imposes a specific language on users without opt-in. The provided policy flags language or locale constraints unless the skill offers a choice or clearly documents a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

Several natural-language messages returned by the skill are fixed in Chinese, including error and login-status text. This forces a specific language/locale without user opt-in or any documented locale constraint, which matches the language policy violation category.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The logout path immediately removes the locally stored token and pending login state. Although this is intentional, it is a destructive local state change and there is no confirmation prompt, cautionary message, or prior disclosure in the script text before the deletion occurs.

Content

No source excerpt is available for this finding.