Back to skill

Security audit

Crop Pest Identification | 经济作物虫害识别

Security checks for vulnerabilities and agentic risk

Overview

This crop-analysis skill needs review because its configuration-only mode can upload media and its account and credential handling lacks clear safeguards.

Prefer a corrected release that honors configuration-only mode, restricts credential destinations, and clearly explains account creation and token storage. Media is sent to lifeemergence.com services. Do not rely on --export-env-only to prevent uploads or --api-url to change their destination; use a dedicated service account and only media intended for cloud processing.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (26)

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The supplied chunk implements user-database infrastructure, not image/video processing, pest-detection API calls, or confidence-score output. Authentication persistence could support a broader API-based skill, but this chunk provides general user management, including demographic fields and destructive CRUD operations, without a visible connection to pest identification. These capabilities are not represented in the declared purpose. No network transmission or token exfiltration is shown, and the finding is limited to the supplied chunk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The analysis commands match the declared purpose, and report formatting and file output are supporting features. However, historical-report listing and its explicitly documented automatic triggers are a distinct capability not disclosed in the description. The underlying Python implementation is not supplied, so server-side API calls and other internal behavior cannot be verified.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

Submitting local or URL-based video for delegated analysis and saving its output are compatible with the declared purpose. However, the code also exposes a separate capability to retrieve analysis history using an open ID, beyond identifying pests in supplied media. The underlying analysis implementation is not included, so this chunk alone cannot establish whether it actually detects agricultural pests, supports images, or returns confidence scores; those uncertainties are not independently treated as mismatches.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
87% confidence
Finding

Generic request handling, polling, and authentication can legitimately support the declared server-side pest detection. However, this helper also implements silent account registration and persistent identity management not disclosed in the description. More significantly, http_request accepts arbitrary absolute URLs and adds X-Access-Token, X-Api-Key, and Authorization headers without checking the destination, creating a credential-disclosure capability beyond pest identification. The chunk contains no pest-specific processing, but that absence alone is not evidence of mismatch because this is a shared utility module. No actual credential leak or invocation of these methods is established by the supplied chunk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
86% confidence
Finding

Media submission and asynchronous result retrieval are consistent with the declared workflow. However, the report-list method calls a separate page API and returns existing analysis records, a data-access capability not disclosed in the description. The supplied chunk does not establish whether the underlying analysis API identifies agricultural pests: its implementation and configuration are absent, and generic response fields alone do not prove a different analysis purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
82% confidence
Finding

Generic AI-analysis endpoints could support the declared workflow and are not themselves a mismatch. However, DETAIL_EXPORT_URL explicitly targets BASE_URL_HEALTH and /health/order/api/getReportDetailExport, introducing an unrelated health-report resource. This supports a configuration-level mismatch, although the chunk alone does not establish that the endpoint is actually called.

Content

No source excerpt is available for this finding.

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
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · SKILL.md (reported line 3)May include surrounding context.

md
---
name: "smyx-crop-pest-identification-analysis"
description: "Triggers when a user provides images or videos of crop leaves, buds or fruits (local file or URL) for pest identification; calls server-side APIs to detect common agricultural pests such as aphids, red spider mites, cotton bollworms and corn borers, outputting pest types with confidence scores. | 当用户提供作物叶片、嫩芽或果实的图像/视频(本地文件或网络URL)时,触发本技能进行虫害识别;调用服务端API检测蚜虫、红蜘蛛、棉铃虫、玉米螟等常见农业害虫,输出虫害类型与置信度。应用场景:番茄/玉米/花

The request helper forwards service credentials to arbitrary absolute URLs, beyond the pest-identification API's authentication needs.

High
Category
Excessive Agency
Confidence
99% confidence
Finding

The helper accepts arbitrary absolute HTTP or HTTPS destinations and then automatically attaches service tokens and the API key without checking the destination's origin. If a caller passes an attacker-controlled URL, those credentials are disclosed; the skill's support for user-provided media URLs makes strict separation between media retrieval and authenticated API requests particularly important.

Content

No source excerpt is available for this finding.

Skill declares no tool scope ('permissions' or 'allowed-tools') but code capabilities were detected: env, file_read, file_write, network, shell.

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

The output heading is unconditionally fixed to Chinese without a user language choice.

Medium
Category
Output Handling
Confidence
90% confidence
Finding

The output-heading method always returns Chinese text, regardless of the user's language or locale preference. No language opt-in or region-specific justification is provided for this fixed-language output.

Content

No source excerpt is available for this finding.

The documented environment-export-only mode still executes pest analysis.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

The parser promises that --export-env-only will not perform analysis, but execution never checks the flag and proceeds to identity initialization and, with valid input, remote analysis. A user relying on this non-executing mode can unintentionally upload local media or trigger cloud processing and associated costs.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
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.

Content

Scanner excerpt · skills/smyx_analysis/scripts/skill.py (reported line 28)May include surrounding context.

python
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

Whitespace Padding

Medium
Category
Prompt Injection
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.

Content

Scanner excerpt · skills/smyx_analysis/scripts/skill.py (reported line 33)May include surrounding context.

python
result_json = result_json_common_ai_response

        result_json_health_ai_response = result_json.get("healthAiResponse") if isinstance(result_json,
                                                                                           dict) else result_json
        if result_json_health_ai_response:
            result_json = result_json_health_ai_response

Local input files are passed to the analysis API without disclosure that their contents leave the system.

Medium
Category
Output Handling
Confidence
88% confidence
Finding

The code reads the entire local file and passes its contents as an upload payload to the analysis service. No prompt, user-facing message, docstring, or comment here explains the remote transmission; requesting file analysis alone does not necessarily imply consent to upload potentially private media.

Content

No source excerpt is available for this finding.

The --export-env-only option promises not to perform analysis, but the code still invokes analysis.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

The --export-env-only option is parsed but never honored, so providing media with this option still reaches remote analysis despite the explicit no-analysis promise. This violates the caller's execution boundary and can disclose media or incur processing costs during an intended configuration-only operation.

Content

No source excerpt is available for this finding.

The skill includes persistent personal-profile management unrelated to crop pest identification.

Medium
Category
Excessive Agency
Confidence
89% confidence
Finding

The User model stores real names, email addresses, birthdays, sex, and age alongside authentication tokens (L448-L465), and UserDao exposes the inherited database CRUD operations (L470-L473). Authentication could reasonably support server-side pest-detection APIs, but maintaining editable demographic profiles is not justified by the manifest's image/video analysis purpose. DAO initialization also creates and migrates the user database schema (L180-L215), making this a persistent account-management capability rather than merely an API request structure.

Content

No source excerpt is available for this finding.

FileUtil.open silently truncates existing files without disclosing its destructive behavior.

Medium
Category
Output Handling
Confidence
96% confidence
Finding

The generic open helper always uses mode 'w', which immediately erases existing file contents. No docstring, explanatory comment, confirmation, or operation log discloses this behavior; the exception handler only handles failures.

Content

No source excerpt is available for this finding.

HTTP requests can silently trigger remote account registration without disclosure.

Medium
Category
Output Handling
Confidence
95% confidence
Finding

An ordinary API request can automatically invoke phoneLogin with silent and register enabled when credentials are missing. This requests remote account creation and sends an identity value without an explicit registration opt-in in the supplied code, introducing a privacy-relevant side effect beyond submitting crop media for analysis.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This POST transmits the selected identity as both openId and mobile, along with the skill-hub source, during automatic login or registration. External API communication is expected for this skill, but undisclosed identity enrollment is distinct from pest-image processing; the identity selection can also use the configured API secret, potentially placing a credential in account fields.

Content

Scanner excerpt · skills/smyx_common/scripts/util.py (reported line 561)May include surrounding context.

python
"source": ConstantEnum.DEFAULT__SKILL_HUB_NAME
            }
            try:
                _response = requests.post(_url, json=_data)
                if _response.status_code == 200:
                    _response_json = _response.json()
                    if _response_json and _response_json.get("success"):

Configuration loading silently creates directories and files, including during module import.

Low
Category
Output Handling
Confidence
94% confidence
Finding

YamlUtil.load creates parent directories and writes a YAML file when the requested configuration is missing, without a warning, log, or explanatory comment/docstring. BaseEnum.init_subclass invokes this loader during class definition (L044–L059), so importing the module can modify the filesystem without explicitly requesting a save.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · skills/smyx_common/scripts/dao.py (reported line 243)May include surrounding context.

python
username = getattr(model, "username", None)
            if username:
                column_names = self.__model__.__table__.columns.keys()
                update_data = {key: getattr(model, key) for key in column_names if key != "username"}
                return self.update_by_username(username, **update_data)

            return None

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · skills/smyx_common/scripts/dao.py (reported line 353)May include surrounding context.

python
column_names = self.__model__.__table__.columns.keys()

            for key in column_names:
                value = getattr(model, key)
                setattr(instance, key, value)

            session.commit()

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · skills/smyx_common/scripts/dao.py (reported line 326)May include surrounding context.

python
if filters:
                for key, value in filters.items():
                    query = query.filter(getattr(self.__model__, key) == value)

            if offset:
                query = query.offset(offset)

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · skills/smyx_common/scripts/dao.py (reported line 441)May include surrounding context.

python
if filters:
                for key, value in filters.items():
                    query = query.filter(getattr(self.__model__, key) == value)

            return query.scalar()
        finally:

The ai_chat docstring claims to invoke openclaw agent through subprocess, but the implementation never invokes it.

Low
Category
Excessive Agency
Confidence
99% confidence
Finding

The docstring at L26 explicitly promises subprocess-based agent invocation, but both command construction and subprocess execution are commented out. Instead, L68 creates an empty dictionary, and L70 accesses its nonexistent stderr attribute; the resulting exception is caught, so the method returns None without performing the documented analysis.

Content

No source excerpt is available for this finding.