Back to skill

Security audit

我家云工单

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches a Wojiayun device and work-order API client, but it ships unsafe credential handling and hidden high-impact side effects that need review before use.

Review this skill carefully before installing. Use only a revocable, least-privilege Wojiayun API key; assume the embedded default key is compromised and should not be trusted. Do not use it where arbitrary base_url changes, local credential files, SQL exports, or the production obfuscation build could expose or damage business data. Prefer a version that removes the hardcoded key, pins the API host, uses proper secret storage, documents uploads and bulk exports, and separates developer build tooling from runtime behavior.

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

T09 · Insecure Skill Coding Practices

Error
Location
wojiayun_skill/key_manager.py:111
Finding

Hard-Coded API Credential Distributed in Source Code

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
wojiayun_skill/token_manager.py:107
Finding

API Key Exposure Through a GET Query String and Mutable Authentication Destination

Content
View full analysis
Tuple[bool, str]: """Refresh the access token.""" import requests try: # Use the complete URL directly url = f"{base_url}/thirdUser/apiKeyAuth" response = requests.get( url, params={"apiKey": api_key}, timeout=30 ) ``` The destination can be replaced without validating the scheme, hostname, port, or origin: ```python def update_base_url(self, new_url: str): """ Update the base URL and encrypt it before storage. Args: new_url: New base URL """ encrypted = encrypt_value(new_url) self._config["base_url"] = { "encrypted": encrypted, "updated_at": datetime.now().isoformat(), } self._save_config() print("✓ base_url updated") ``` The mutable value is loaded into the API client: ```python def _load_config(self): """Load configuration for internal use.""" self._base_url = self.config.get_base_url() for name in self.config.list_endpoints(): self._endpoints[name] = self.config.get_endpoint(name) ``` Automatic token refresh retrieves the stored API key and sends it to that destination: ```python api_key = get_api_key() if api_key: success, message = tm.refresh_access_token(api_key, self._base_url) ``` ### Technical Analysis Sensitive credentials should not be placed in URL query strings. URLs are commonly recorded by reverse proxies, application servers, observability systems, error reports, and network security products. Although the default endpoint uses HTTPS, transport encrypti ...[truncated 2333 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
wojiayun_skill/crypto_utils.py:17
Finding

Predictable At-Rest Encryption and Missing Credential-File Permission Controls

Content
View full analysis
str: """Get a machine identifier as the encryption password.""" machine_id = f"{os.environ.get('COMPUTERNAME', 'default')}{os.environ.get('USERNAME', 'user')}" return hashlib.sha256(machine_id.encode()).hexdigest()[:32] def _derive_key(self, password: str) -> bytes: """Derive a Fernet-compatible key from a password.""" salt = b'equipment_analyzer_salt_2024' kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, ) key = base64.urlsafe_b64encode(kdf.derive(password.encode())) return key ``` API keys are written without explicit restrictive permissions: ```python STORAGE_FILE = "e:\\workbuddy\\wy\\.secure_keys" def _save_keys(self): """Save keys to a file.""" with open(self.STORAGE_FILE, 'w', encoding='utf-8') as f: json.dump(self._keys, f, ensure_ascii=False, indent=2) ``` Access tokens use the same pattern: ```python TOKEN_FILE = "e:\\workbuddy\\wy\\.secure_tokens" def _save_tokens(self): """Save tokens to a file.""" with open(self.TOKEN_FILE, 'w', encoding='utf-8') as f: json.dump(self._tokens, f, ensure_ascii=False, indent=2) ``` ### Technical Analysis The confidentiality of the stored API keys and access tokens depends on a key d ...[truncated 2210 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
wojiayun_skill/mode_manager.py:63
Finding

Runtime Mode Change Silently Triggers Destructive Obfuscation Build

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (32)

Hidden Instructions

High
Category
Prompt Injection
Confidence
60% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 1)May include surrounding context.

md
# Wojiayun Skill - 我家云设备管理与工单系统

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module decrypts and returns stored API keys, which is a sensitive credential access operation, but provides no user-facing disclosure when this occurs. In addition, the test initializer embeds and stores an API key value directly, increasing the sensitivity of the operation without any warning to users.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The function init_default_key() writes a hardcoded API key-like secret to persistent storage, which creates an embedded credential in source code and on disk. Even if labeled as 'for testing', hardcoded secrets are commonly leaked through source control, packaging, logs, backups, or accidental execution in production-like environments.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
88% confidence
Finding

get_system_prompt() returns the plaintext system prompt directly to any caller of the wrapper, which defeats the stated goal of preventing users from viewing protected prompts if this object is reachable from less-trusted code. In an agent skill context, exposing the system prompt can reveal hidden instructions, safety logic, tool-routing behavior, or other sensitive prompt content that attackers can use for prompt extraction or bypass attempts.

Content

Scanner excerpt · wojiayun_skill/secure_prompt_manager.py (reported line 94)May include surrounding context.

python
if not prompt:
            # 默认提示词
            prompt = "你是一个专业的设备管理助手。"
        return prompt

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · wojiayun_skill/token_manager.py (reported line 2)May include surrounding context.

python
"""
Access Token 管理模块
实现 token 失效检测和自动刷新
"""

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · wojiayun_skill/token_manager.py (reported line 20)May include surrounding context.

python
"""
Access Token 管理模块
实现 token 失效检测和自动刷新
"""

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · wojiayun_skill/token_manager.py (reported line 134)May include surrounding context.

python
"""
Access Token 管理模块
实现 token 失效检测和自动刷新
"""

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill documents a file upload capability but does not warn users that files will be transmitted to a remote service, nor does it explain privacy, retention, or handling implications. In a device/work-order management context, uploads may contain photos, videos, or documents with sensitive operational or personal data, so omission of this notice can lead to unintended data disclosure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The module docstring at L01-L03 presents the skill as a 'device data analysis' skill, which implies an analytics-focused purpose. However, the package exports functions and classes for API key storage, encryption/decryption, secure API access, prompt management, and token expiration handling, which materially extend beyond simple data analysis and make the documentation misleading about the skill's actual capabilities.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The top-level documentation states the module uses an AES symmetric encryption algorithm to protect sensitive data. However, the code constructs a cryptography.fernet.Fernet instance and performs encryption/decryption through Fernet tokens, which is a different API and documented abstraction than the stated implementation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This file’s natural-language interface elements, including the module docstring, class docstring, and parameter documentation, are entirely in Chinese. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation, and no alternative language or opt-in mechanism is documented here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill is designed to automatically retrieve all device data across all pages and store it in memory, but it provides no user-facing warning, consent step, scoping control, or sensitivity check before performing bulk collection. In an equipment-management context, full device inventories can expose operational details, locations, maintenance assignments, and other sensitive organizational data that increase reconnaissance and data-leak risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill’s stated purpose is device data fetching and statistical analysis, but it also includes a bulk export_to_sql() function that writes all retrieved equipment records to a local SQL file. This materially expands the data-handling surface and enables easy persistence and exfiltration of potentially sensitive asset inventory data without any access scoping, minimization, confirmation, or safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code writes encrypted key metadata to a fixed local file path, and related logic later deletes stored keys, but there is no confirmation prompt or user-facing notice around these state-changing file operations. Although docstrings describe the functions, they do not serve as a clear user disclosure that secret material will be persisted to disk at a specific location.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module docstring and class docstring both describe the component as '运行环境配置' (runtime environment configuration), implying simple mode/config state management. However, calling apply("B") invokes _build_production(), which imports an obfuscator and builds a production/obfuscated version of code, a materially different side effect not reflected in the documentation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
77% confidence
Finding

In a file presented and documented as a runtime profile/configuration manager, the apply method does more than persist mode state: it conditionally triggers a production build via an obfuscator. With no manifest available and no stated purpose beyond runtime configuration in code docs, bundling build/obfuscation functionality into this component is an unjustified extra capability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The apply() method writes to a persistent config file and, when switching to production mode, automatically invokes a build operation. While the code comments describe the behavior, there is no user-facing disclosure such as a prompt, print/log message, or other visible warning before these state-changing actions occur.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code writes a Python setup script to disk and then executes it, creating a code-execution boundary based on generated file content and filesystem paths. If an attacker can influence source_file, output_dir, or the build environment, they may be able to trigger unintended code execution or overwrite files, and the absence of safety restrictions increases the blast radius in compromised or multi-user environments.

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 · wojiayun_skill/obfuscator.py (reported line 173)May include surrounding context.

python
# 执行编译
        import subprocess
        result = subprocess.run(
            [sys.executable, setup_file],
            capture_output=True,
            text=True

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The production build unconditionally deletes and recreates a fixed absolute directory, which can cause destructive data loss if the path is misconfigured, reused, or points to unexpected content. Because OBF_DIR is hard-coded and shutil.rmtree is called without confirmation, safety checks, or path validation, a user running this tool can erase files outside the intended build context.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module advertises itself as a secure configuration manager, but it also contains active network request execution and token-refresh behavior. This mismatch can mislead downstream users or reviewers into granting the code more trust than warranted, reducing scrutiny over outbound communications and authenticated actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The client performs live outbound requests and can send authorization headers, request data, and API-key-derived token refresh traffic without any explicit user-facing disclosure or consent gate. In a skill context, this can cause silent transmission of sensitive credentials or business data to remote services, especially because token refresh is automatic.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The code issues outbound POST requests to decrypted URLs with caller-supplied JSON bodies and headers, including authorization data. Even though the base URL is preset and uses HTTPS by default, the file also allows updating the base URL and automatically refreshes tokens, increasing the risk of sensitive data transmission to unintended endpoints if configuration is altered or abused.

Content

Scanner excerpt · wojiayun_skill/secure_api_config.py (reported line 379)May include surrounding context.

python
if method.upper() == "GET":
                response = requests.get(url, headers=headers, timeout=30)
            elif method.upper() == "POST":
                response = requests.post(url, json=data, headers=headers, timeout=30)
            else:
                return {"error": f"不支持的 HTTP 方法: {method}"}

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module claims prompts are protected from viewing and tampering, but this file provides only confidentiality-by-encryption and no integrity protection or access control. Any code with access to this class can retrieve decrypted prompts, and the on-disk JSON can be modified without any signature, MAC, or authenticated-encryption verification to detect tampering.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
wojiayun_skill/crypto_utils.py:26