Back to skill

Security audit

TCM Facial Diagnosis Analysis Tool | 中医面诊分析工具

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a remote facial-analysis skill, but it needs review because it can upload sensitive videos, silently bind activity to a local/cloud identity, and persist service tokens without clear user control.

Install only if you are comfortable sending facial videos or supplied video URLs to the Life Emergence remote service for health-style analysis and having report history associated with an automatically managed identity. Prefer use with non-sensitive, consented media, and review token storage, dependency pinning, and endpoint scoping before production or regulated use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
skills/smyx_common/scripts/util.py:568
Finding
Authentication Credentials Can Be Forwarded to Arbitrary Request Origins and Are Persisted in Plaintext<![CDATA[ ## Vulnerability Details **File Location**: `skills/smyx_common/scripts/util.py:568-608, 642`; related plaintext storage at `skills/smyx_common/scripts/dao.py:460-462` **Vulnerability Type**: Unrestricted credential forwarding and plaintext token storage **Risk Level**: High ### Vulnerable Code ```python if not url.startswith("https://") and not url.startswith("http://"): url = cls.BASE_URL + url headers['App-Id'] = ConstantEnum.APP__ID if not (ApiEnum.API_SECRET_KEY or ConstantEnum.CURRENT__USER_NAME or ConstantEnum.CURRENT__OPEN_ID): OpenIdUtil.resolve_current_open_id(use_current=False) current__user_name = ( ApiEnum.API_SECRET_KEY or ConstantEnum.CURRENT__USER_NAME or ConstantEnum.CURRENT__OPEN_ID ) found_user = None if (not ApiEnum.TOKEN or not ApiEnum.OPEN_TOKEN) and current__user_name: try: from .dao import UserDao, User user_dao = UserDao() found_user = user_dao.get_by_username(current__user_name) if found_user: ApiEnum.TOKEN = found_user.token ApiEnum.OPEN_TOKEN = found_user.open_token current__user_name = found_user.username if not ApiEnum.TOKEN or not ApiEnum.OPEN_TOKEN: new_current_user = _get_or_create_user(current__user_name) if new_current_user: ApiEnum.TOKEN = new_current_user.get("token") ApiEnum.OPEN_TOKEN = new_current_user.get("openToken") current_user_info = new_current_user.get("userInfo") if current_user_info: current_user_info["token"] = new_current_user.get("token") current_user_info["openToken"] = new_current_user.get( "openToken") user_model = User.load(current_user_info) user = user_dao.save( user_model ) except Exception as e: CommonUtil.trace_exception_stack(e) raise ...[truncated 3302 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce a strict allowlist of trusted HTTPS origins before attaching credentials: - Parse URLs with `urllib.parse.urlsplit`. - Require `scheme == "https"`. - Compare the normalized hostname and port against configured first-party origins. - Reject user-info components, unexpected ports, redirects to untrusted origins, and malformed hostnames. 2. Separate authenticated and unauthenticated clients: - Use a dedicated first-party API client that always targets a fixed base URL. - Use a separate generic client for remote media URLs that never receives authentication headers. 3. Do not attach credentials merely because a URL is absolute. Add authentication only after confirming that the destination matches the intended API origin. 4. Disable automatic forwarding of sensitive headers across redirects, or disable redirects and validate every redirect destination explicitly. 5. Reject plain HTTP for all authenticated requests. 6. Store tokens in an operating-system credential manager or encrypted secret store. If SQLite storage is unavoidable: - Encrypt token values using a key stored outside the database. - Restrict database and parent-directory permissions to the current user. - Define token expiration and rotation behavior. - Remove stale tokens when authentication fails or the Skill is uninstalled. 7. Add tests proving that credentials are absent when requesting an unknown host, alternate port, plain HTTP URL, or cross-origin redirect. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Incorrect Root Dependency Name Creates Dependency-Confusion Risk<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-3` **Vulnerability Type**: Ambiguous or incorrect third-party package declaration **Risk Level**: Medium ### Vulnerable Code ```text pydash==8.0.6 SQLAlchemy==2.0.46 yaml==6.0.3 ``` The corresponding nested dependency manifest uses the intended distribution name: ```text pydash==8.0.6 SQLAlchemy==2.0.46 PyYAML==6.0.3 ``` ### Technical Analysis The source imports the module as `yaml`, but the standard Python distribution providing that module is named `PyYAML`. The root dependency manifest instead requests a distribution named `yaml`. Python import names and package-index distribution names are not interchangeable. Installing the root manifest may therefore fail, resolve an unintended package, or create an opportunity for dependency confusion if a package with the requested name is available from the configured package index. The inconsistency between the root and nested manifests also makes installation behavior dependent on which requirements file an operator uses. Third-party packages may execute code during installation or when imported. Resolving an unintended distribution can therefore affect the host with the privileges of the installer. ### Attack Path 1. A user or deployment process installs dependencies from the root `requirements.txt`. 2. The package manager resolves the distribution named `yaml` rather than the intended `PyYAML` distribution. 3. If the configured package source contains an unintended or malicious package under that name and version, it is downloaded and installed. 4. Package installation hooks or subsequently imported package code execute with the permissions of the installation process. This path depends on package availability and package-index configuration; the audit did not establish that a malicious package is currently resolved. ### Impact Assessment A malicious dependency could execute arbitrary Python code with the privileges of the user or ...[truncated 236 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the incorrect dependency declaration: ```text PyYAML==6.0.3 ``` 2. Keep the root and nested requirements files consistent, preferably by maintaining one authoritative lockfile. 3. Pin dependencies with cryptographic hashes, for example by using `pip-compile --generate-hashes`. 4. Configure package installation to use an explicitly trusted index and avoid untrusted fallback indexes. 5. Add automated dependency checks that compare import requirements with declared distribution names and flag inconsistent manifests. 6. Review all pinned versions with a software composition analysis tool and update them according to a documented patch policy. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (52)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The reported behavior includes local file operations, identity material reads, local DAO operations, automatic user registration/login, generic authenticated HTTP access, token persistence, and debug logging—far broader than the stated face-diagnosis workflow. In the context of medical video analysis, this is especially dangerous because it combines sensitive content with identity linkage, persistent auth state, and opaque remote interactions.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
---
name: "face-analysis"
description: "Supports uploading local MP4 videos or network video URLs to call the server-side API for facial diagnosis. It returns structured TCM facial diagnosis results. | 支持通过上传本地 MP4 视频或网络视频 URL,调用服务端 API 进行面部诊断,返回结构化的中医面诊结果"
version: "1.0.6"
license: "MIT-0"
---

# 🧑‍⚕️ TCM Facial Diagnosis Analysis Tool | 中医面诊分析工具
> **智能分析中枢** · 图片/视频智能分析 · 结构化报告 · 历史报告云端查询

---

## 🧭 技能概览 | Overview

| 模块 | 内容 |
|---|---|
|
Confidence
84% confidence
Finding
The YARA hit for metadata/tool poisoning indicators suggests the manifest may contain suspicious formatting or content designed to influence tooling or evade normal review. In combination with the extensive description-behavior mismatches, this raises concern that metadata is being used to misrepresent the skill's true capabilities.

Vague Triggers

High
Confidence
96% confidence
Finding
The default trigger activates for generic video or file analysis requests whenever the user has not explicitly asked for other kinds of analysis. This can cause the agent to send videos or URLs to a server-side health-analysis workflow without sufficiently specific user intent, increasing privacy and consent risks.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill manifest describes facial diagnosis over uploaded or remote videos, but this configuration redirects analysis calls to pet health-analysis endpoints. This mismatch can cause the skill to process the wrong data domain, send user media to an unintended backend workflow, or return misleading medical-style results, creating a serious integrity and privacy risk. In a health-related skill, incorrect endpoint wiring is more dangerous because users may rely on inaccurate diagnostic output.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill manifest declares executable behavior involving shell, file I/O, environment access, and network/API usage, but does not constrain those capabilities with explicit tool scope metadata. In an agent setting, this increases the risk of unintended or overly broad tool use and makes review, sandboxing, and policy enforcement harder.

Natural-Language Policy Violations

Medium
Confidence
79% confidence
Finding
The skill name, core goal, trigger rules, workflow, and examples are primarily written to operate in Chinese terms and phrases, but the document does not state that this locale is optional or region-specific. Because there is no explicit user choice or opt-in for language/locale, this may violate language policy expectations.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The description emphasizes analysis features but does not clearly warn users that local videos or supplied URLs are transmitted to a server-side API for processing. For sensitive biometric and health-adjacent data, lack of explicit transmission disclosure undermines informed consent and increases data-exposure risk.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The documentation instructs users to upload facial videos or provide public video URLs to a remote server for analysis, but it does not disclose privacy risks, biometric sensitivity, retention, sharing, or consent requirements. Because facial video is highly sensitive biometric/health-adjacent data and the skill returns diagnosis-style results, omission of privacy and handling guidance can lead to unsafe collection, transfer, and processing of regulated personal data.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The inline comment describes the file as a pet health diagnosis analysis tool, which contradicts the declared face-analysis skill purpose. While a comment alone is not executable, this inconsistency is a strong indicator of copy-paste or component-reuse errors that can conceal functional misrouting to the wrong service, especially when paired with the endpoint mismatch in this file.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The function forwards either a local video path or remote video URL to `skill.get_output_analysis(...)`, which the skill description states invokes a server-side API, but the script provides no explicit warning that potentially sensitive biometric/medical video data will be transmitted off-host. In this context, face-analysis data is especially privacy-sensitive, so lack of informed disclosure increases the risk of unintended exfiltration of local content or third-party URLs.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script resolves an internal/open ID automatically via `OpenIdUtil.resolve_current_open_id(...)` without clear user-facing disclosure or consent at runtime. Because this skill handles medical-style face analysis and history lookup, silently binding requests to a user identity can expose or retrieve sensitive personal data under an identity the user did not explicitly choose.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Multiple returned user-facing strings are hard-coded in Chinese, such as the analysis header and export-link text, and the file does not provide any opt-in or locale selection. This creates a language-policy issue because the skill imposes a specific language on all users regardless of preference or context.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
When a local path is provided, the code reads the entire file and uploads it to a server-side API (`files = {'file': ...}`) without any user-facing confirmation, warning, or explicit consent mechanism in this file. In a skill that handles local media, this creates a real privacy and data-exfiltration risk, especially if users may not realize their local video contents are transmitted off-host for analysis.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The method name `SMYX_HYDROPONIC_NUTRIENT_ASSESSMENT_ANALYSIS` describes an unrelated hydroponic nutrient assessment capability, while its docstring and implementation clearly operate on facial diagnosis report history. This is an active contradiction in developer-facing intent signals and can mislead auditors or downstream tooling about the skill's true purpose.

Whitespace Padding

Medium
Category
Prompt Injection
Content
result_json = JsonUtil.parse(result_json_pure_text, result_json_pure_text)

        result_json_common_ai_response = result_json.get("commonAiResponse") if isinstance(result_json,
                                                                                           dict) else result_json
        if result_json_common_ai_response:
            result_json = result_json_common_ai_response
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
result_json = JsonUtil.parse(result_json_pure_text, result_json_pure_text)

        result_json_common_ai_response = result_json.get("commonAiResponse") if isinstance(result_json,
                                                                                           dict) else result_json
        if result_json_common_ai_response:
            result_json = result_json_common_ai_response
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Static analysis

Detected: suspicious.install_untrusted_source

Install source points to URL shortener or raw IP.

Warn
Code
suspicious.install_untrusted_source
Location
skills/smyx_common/scripts/config-dev.yaml:2