Back to skill

Security audit

Pet Race Foul Detection (False Start / Lane Crossing) | 宠物赛跑/竞赛作弊识别(起跑/窜道)

Security checks for vulnerabilities and agentic risk

Overview

This skill needs review because its account handling can mix users’ reports, it stores reusable credentials locally, and an option meant to prevent analysis is ignored.

Prefer waiting for fixes before using this in shared or sensitive workspaces. Submitted files are uploaded to LifeEmergence’s service, and supplied URLs are forwarded for remote retrieval. Require reliable per-user account separation, protected token storage, separation of API secrets from identity fields, restricted credential destinations and a working export-only mode.

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/smyx_race_foul_detection_analysis.py:60
Finding

Default CLI initialization discards the upstream sender identity and reuses a workspace-wide account

Content
View full analysis

Impact

Under the stated shared-workspace conditions, one sender can receive another sender's report history and report links. Analyses are also associated with the shared account rather than the supplied sender identity.

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

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The supplied chunk implements a general-purpose user database layer, including a sys_user model with names, email, demographics, and token fields. It contains no video processing, animal tracking, timing, lane detection, foul detection, or judgment generation. Database persistence could support a larger skill, but this chunk specifically manages users and credentials without any demonstrated connection to the declared racing-analysis purpose. This assessment is limited to the supplied code; it does not establish that other parts of the skill lack the advertised analysis functionality or that stored data is transmitted externally.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied implementation does not substantiate the declared core functionality. Its intended external agent invocation is disabled, and its active result-handling path fails because a dictionary has no stderr attribute. Imported base classes and API services are not supplied, so their behavior cannot be verified; the mismatch assessment is limited to this code chunk. There is no evidence here of active subprocess execution or malicious behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The substantive security issue is the reported forwarding of authentication credentials and identity metadata to caller-supplied destinations, not merely the presence of login or billing functionality. Combined with the documented --api-url override, unrestricted credential forwarding could disclose reusable tokens to an attacker-controlled endpoint; the implementation is not supplied, so this conclusion depends on the static analyzer's reported behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The video-analysis commands align with the declared purpose, and report formatting and saving are supporting features. However, the explicit history-listing operation and its keyword triggers extend beyond the declared video-input workflow. The snippet does not reveal how history is stored or whether the underlying module actually implements the claimed video analysis.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The video-analysis entry point is broadly consistent with the description, although the imported implementation is not supplied, so the claimed racing-specific detection cannot be verified. The concrete mismatch is the independent history-listing capability: --list invokes get_output_analysis_list with the current user's open ID and prints the result without analyzing a supplied race video. This is an additional user-data retrieval function, not merely an internal step in the declared video judgment workflow. Identity resolution and optional result-file writing are otherwise supporting implementation details.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Generic AI-analysis endpoints could support the declared functionality and are not inherently a mismatch. However, the explicitly configured health-order report export endpoint is an inconsistent resource not explained by the description. This is configuration only: it does not demonstrate that any request or export actually occurs. The absence of video-analysis logic in this isolated chunk is not, by itself, evidence of a mismatch.

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-race-foul-detection-analysis"
description: "Triggers when a user provides a pet racing track start/finish video URL or file for analysis; uses HD cameras at the starting line and finish line to analyze race video in real time, detecting each pet's (greyhounds, racehorses, etc.) start time, finish order, and lane assignment, automatically determining false starts (start before the signal) or lane crossing (deviating from own lane into an adjacent lane) fouls and outputting judgment results. Assists referee decisions and improves race fairness. Application: pet racing (greyhound, horse, obstacle course), pet sports events, p

The HTTP helper can send platform credentials and user identity to arbitrary absolute URLs.

High
Category
Excessive Agency
Confidence
98% confidence
Finding

The helper accepts arbitrary absolute HTTP or HTTPS URLs and attaches platform tokens, the API key, and user identity without validating the destination. If an untrusted video URL or other attacker-controlled destination reaches this helper, credentials can be sent to an attacker; accepting HTTP also permits plaintext transmission. The video-URL workflow makes destination separation particularly important, although that call path is not shown here.

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
76% confidence
Finding

The manifest declares no tool scope despite directing shell execution, local file handling, and remote API access. This is a least-privilege gap where the agent runtime otherwise grants broad tools, although omission alone does not demonstrate a sandbox escape or unrestricted access.

Content

No source excerpt is available for this finding.

The analysis workflow lacks a user-facing privacy warning about remote processing of submitted race footage.

Medium
Category
Output Handling
Confidence
92% confidence
Finding

Although the technical documentation mentions cloud processing, the workflow does not require telling the user before local footage or supplied URLs are sent to an external service. Race footage can contain identifiable handlers, spectators, or private venue information, creating a meaningful disclosure risk when users reasonably expect local analysis.

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 video contents are submitted to the analysis API without disclosure of the upload.

Medium
Category
Output Handling
Confidence
87% confidence
Finding

The code reads the entire local file and passes its contents to the analysis API as a file attachment. No prompt, log, docstring, or comment in this file explains that analysis transfers the video to a service; requesting video analysis does not necessarily imply consent to remote processing.

Content

No source excerpt is available for this finding.

The --export-env-only option promises not to analyze video but does not prevent analysis.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

The --export-env-only flag explicitly promises not to perform analysis, but its parsed value is never checked, so a command that also supplies a video proceeds to skill.get_output_analysis. In this API-backed video-analysis context, this can unexpectedly process potentially sensitive footage or trigger service requests and costs despite the caller selecting a non-processing mode; the exact data transfer depends on the unseen implementation.

Content

No source excerpt is available for this finding.

The skill exposes account analysis history independently of analyzing a supplied race video.

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

The --list branch retrieves and prints an account's historical analyses through show_analyze_list, without requiring a video input. The manifest limits the skill to judging supplied race videos and does not declare access to historical account records.

Content

No source excerpt is available for this finding.

The service exposes username-based user lookup, a capability outside the stated video-analysis purpose.

Medium
Category
Excessive Agency
Confidence
86% confidence
Finding

At L098–L101, get_user_by_username forwards a supplied username to a user-lookup utility. Looking up user accounts is not an obvious requirement for detecting starts, finish order, lane assignments, or fouls, and the manifest does not declare account lookup as part of the skill's scope.

Content

No source excerpt is available for this finding.

The skill includes persistent user-profile and credential management unrelated to video-based race judging.

Medium
Category
Excessive Agency
Confidence
96% confidence
Finding

The user model persists token and open_token as ordinary string columns in SQLite, with no application-level encryption or restrictive file-permission enforcement shown. If populated with live credentials, access to the database or its backups could expose them; their presence is unnecessary for the stated video-judging purpose, although this file does not demonstrate malicious collection or exfiltration.

Content

No source excerpt is available for this finding.

ai_chat documents invoking an analysis agent, but its implementation never invokes the agent or returns analysis.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

The docstring at L26 explicitly claims that this method invokes openclaw agent through subprocess, and L33-L34 promise an analysis result or session ID. However, the invocation is commented out at L61-L66; L68 instead creates an empty dictionary, whose .stderr access raises an AttributeError that is caught at L81-L82, causing the method to return None without performing analysis.

Content

No source excerpt is available for this finding.

FileUtil.open silently truncates existing files without disclosing its destructive write mode.

Medium
Category
Output Handling
Confidence
96% confidence
Finding

Opening a path with mode 'w' immediately erases any existing contents, even before the caller writes anything. This generic open helper provides no confirmation, explanatory comment or docstring, or user-facing notice about that behavior; its exception handler only runs after a failure.

Content

No source excerpt is available for this finding.

The request helper silently registers remote users and persists account credentials, beyond the declared video-judgment behavior.

Medium
Category
Excessive Agency
Confidence
92% confidence
Finding

An ordinary request can implicitly trigger remote registration using silent=1 and register=1, transmit the selected identity, and persist returned account tokens through the DAO. This introduces account creation and identity processing beyond the declared video-judgment function without a consent gate in this file; credential-storage protections cannot be determined without the DAO implementation.

Content

No source excerpt is available for this finding.

HTTP requests can implicitly register a remote account without disclosure.

Medium
Category
Output Handling
Confidence
93% confidence
Finding

The login payload explicitly requests silent registration, allowing a routine API operation to create a remote account without a separate approval step in the visible code. This is the same undisclosed account-provisioning issue identified by SDI-1, rather than an additional independent vulnerability.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

External API communication is not inherently unsafe, but this particular request transmits identity fields as part of implicit account registration. Moreover, the caller prioritizes API_SECRET_KEY as the username, so a configured secret can be duplicated into the openId and mobile JSON fields, potentially exposing it to identity storage or logging; this overlaps the registration findings.

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"):

The --export-env-only option promises not to run analysis, but analysis still executes.

Low
Category
Excessive Agency
Confidence
99% confidence
Finding

The --export-env-only flag explicitly promises not to execute analysis, but its parsed value is never checked; when a video input is supplied, execution proceeds through identity resolution and skill.get_output_analysis(). This violates the user's requested execution boundary and could cause unintended processing of potentially sensitive race footage, including any network activity or costs implemented by the downstream skill, although those effects cannot be confirmed from this file alone.

Content

No source excerpt is available for this finding.

Configuration loading silently creates directories and YAML 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 absent, without a comment, docstring, log, or confirmation disclosing this side effect. BaseEnum.init_subclass invokes this loader at L053 and L058, so defining the configuration classes during import can modify the filesystem unexpectedly.

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