Back to skill

Security audit

test-restaurant-inspection

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says: it uses Ezviz credentials to capture restaurant camera images, manage an Ezviz AI agent, and send images to Ezviz for analysis, with the main risks disclosed.

Install only if you are comfortable giving the skill Ezviz API credentials that can capture camera images and create/use Ezviz AI agents. Prefer environment variables or a secrets manager rather than command-line secrets, use least-privilege Ezviz credentials, and confirm your privacy/compliance obligations before sending restaurant camera imagery to Ezviz AI services.

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

Warning
Location
scripts/restaurant_inspection.py:264
Finding

Application Secret Exposed Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/restaurant_inspection.py:264-269
Vulnerability Type: Sensitive credential exposure through process arguments
Risk Level: Medium

Complete Code Snippet

python
if len(sys.argv) >= 4:
    app_key = sys.argv[1]
    app_secret = sys.argv[2]
    device_serial = sys.argv[3]
    if len(sys.argv) >= 5:
        channel_no = sys.argv[4]

Technical Analysis

The script accepts the Ezviz application secret as a positional command-line argument. Command-line arguments can be exposed through shell history, process inspection utilities, endpoint monitoring systems, CI/CD job metadata, diagnostic reports, and command logging.

Accepting the secret this way is unnecessary because the implementation already supports the EZVIZ_APP_SECRET environment variable. The project documentation also explicitly advertises the insecure command-line invocation method.

Attack Path

  1. A user starts the Skill with the documented positional arguments, including the Ezviz application secret.
  2. The secret becomes part of the process command line and may also be stored in shell history or execution logs.
  3. A local user, monitoring agent, log reader, or other process with permission to inspect process metadata obtains the secret.
  4. The attacker combines the secret with the associated application key.
  5. The attacker requests an access token from the Ezviz API and invokes APIs allowed by the compromised credentials.

Impact Assessment

Disclosure can allow unauthorized use of the Ezviz application identity. The resulting access is bounded by the permissions assigned to the application credentials, but may include token acquisition, camera image capture, device identifier access, intelligent-agent management, and image analysis. This may expose restaurant surveillance imagery and permit consumption of account quotas or creation of unwanted intelligent agents.

Remediation
View remediation

Remediation Suggestions

  • Remove support for passing app_secret as a positional command-line argument.
  • Require secrets to be supplied through a protected secret manager or environment variable.
  • For interactive use, optionally obtain the secret with Python's getpass module so it is not echoed or placed in shell history.
  • Update SKILL.md to remove command examples containing secrets as positional arguments.
  • Ensure CI/CD systems inject credentials through masked secret variables.
  • Recommend narrowly scoped Ezviz credentials and regular credential rotation.
  • Document an incident-response procedure for revoking credentials that may already have appeared in process logs or shell history.

T08 · Insecure Dependencies

Note
Location
SKILL.md:24
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:24-28
Vulnerability Type: Uncontrolled dependency version resolution
Risk Level: Low

Complete Code Snippet

bash
pip install requests

Technical Analysis

The installation instructions install requests without a version constraint, lock file, or integrity hash. Consequently, each installation can resolve to a different package release that has not necessarily been reviewed with the Skill.

The package name is legitimate and the audit found no evidence of typosquatting or an intentionally malicious dependency. Nevertheless, unconstrained resolution increases supply-chain exposure: a compromised upstream release, package-index incident, or incompatible future version could be installed automatically.

Attack Path

  1. An attacker compromises a future upstream package release or the dependency distribution path used by the victim.
  2. A user follows the documented pip install requests command.
  3. Package resolution selects the uncontrolled release.
  4. The package is installed in the user's Python environment.
  5. Malicious or compromised dependency code executes when imported or otherwise invoked, with the privileges of the user running the Skill.

This exploitation path is conditional on compromise of the package or its distribution channel; no such compromise was observed in the audited project.

Impact Assessment

A compromised dependency would execute with the same operating-system privileges as the Skill. It could potentially access the process environment, including Ezviz credentials, intercept network requests and responses, modify inspection results, access files available to the user, or communicate with external systems. The precise scope depends on the runtime account and environment isolation.

Remediation
View remediation

Remediation Suggestions

  • Add a reviewed dependency manifest rather than relying on an unconstrained installation command.
  • Pin requests and its transitive dependencies to tested versions.
  • Generate and verify cryptographic hashes, such as with pip-tools and pip install --require-hashes.
  • Use a lock file and a controlled package index or trusted mirror in production.
  • Enable automated dependency vulnerability monitoring and periodically update pins after testing.
  • Run the Skill in an isolated virtual environment or container under a minimally privileged account.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

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: test-restaurant-inspection
description: 餐厅AI巡检自动化。自动管理智能体(检测/创建)、设备抓图、AI分析,实现食品安全/卫生/合规性自动巡检。
metadata:
  openclaw:
    emoji: "🍽️"
    requires: 
      env: ["EZVIZ_APP_KEY", "EZVIZ_APP_SECRET", "EZVIZ_DEVICE_SERIAL"]
      pip: ["requests"]
    primaryEnv: "EZVIZ_APP_KEY"
    sideEffects:
      - "查询萤石智能体列表"
      - "自动创建餐厅专用智能体(模板ID: f4c255b2929e463d86e9)"
      - "设备抓拍图片"
      - "调用AI分析接口"
---

# Ezviz Restaurant Inspection (萤石餐厅巡检)

通

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 · SKILL.md (reported line 110)May include surrounding context.

md
return os.getenv(env_var) or arg_value or default

def get_access_token(app_key, app_secret):
    """Get access token from Ezviz API"""
    print("=" * 70)
    print("[Step 1] Getting access 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 · scripts/restaurant_inspection.py (reported line 39)May include surrounding context.

python
return os.getenv(env_var) or arg_value or default

def get_access_token(app_key, app_secret):
    """Get access token from Ezviz API"""
    print("=" * 70)
    print("[Step 1] Getting access 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 · scripts/restaurant_inspection.py (reported line 41)May include surrounding context.

python
return os.getenv(env_var) or arg_value or default

def get_access_token(app_key, app_secret):
    """Get access token from Ezviz API"""
    print("=" * 70)
    print("[Step 1] Getting access 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 · scripts/restaurant_inspection.py (reported line 311)May include surrounding context.

python
return os.getenv(env_var) or arg_value or default

def get_access_token(app_key, app_secret):
    """Get access token from Ezviz API"""
    print("=" * 70)
    print("[Step 1] Getting access 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 · scripts/restaurant_inspection.py (reported line 314)May include surrounding context.

python
return os.getenv(env_var) or arg_value or default

def get_access_token(app_key, app_secret):
    """Get access token from Ezviz API"""
    print("=" * 70)
    print("[Step 1] Getting access token...")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
97% confidence
Finding

The skill documents use of environment variables and external network calls, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates a governance gap: a user or platform may not have a machine-readable restriction on what the skill can access, increasing the risk of over-broad execution or hidden side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file presents the skill description in Chinese and the rest of the instructions also primarily target Chinese readers, but it does not offer users a language/locale option or explain that the skill is intentionally limited to a Chinese-speaking audience. This can violate language-choice policy for skills intended for general use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script explicitly supports passing app_key and app_secret via command-line arguments, which can expose secrets through shell history, process listings, job logs, and orchestration metadata. Although this is common in utility scripts, it creates avoidable credential leakage risk, especially in shared hosts or CI environments.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/restaurant_inspection.py (reported line 88)May include surrounding context.

python
agents = []
        # Handle both response formats
        if 'data' in result:
            if isinstance(result['data'], dict) and 'appList' in result['data']:
                agents = result['data']['appList']
            elif isinstance(result['data'], list):
                agents = result['data']

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/restaurant_inspection.py (reported line 89)May include surrounding context.

python
agents = []
        # Handle both response formats
        if 'data' in result:
            if isinstance(result['data'], dict) and 'appList' in result['data']:
                agents = result['data']['appList']
            elif isinstance(result['data'], list):
                agents = result['data']

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The script sends captured image URLs from restaurant surveillance devices to an external AI analysis endpoint, which can expose sensitive operational, employee, and customer data to a third-party service. In this skill's context, the captured images may contain PII, food handling practices, and live premises details, making external transmission materially risky if not explicitly consented to and governed.

Content

Scanner excerpt · scripts/restaurant_inspection.py (reported line 231)May include surrounding context.

python
}
    
    try:
        response = requests.post(ANALYSIS_URL, headers=headers, json=payload, timeout=60)
        result = response.json()
        
        if result.get('meta', {}).get('code') == 200:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file description and behavior are centered on Chinese-language operation, and the default analysis prompt is hard-coded in Chinese. There is no indication that the user can choose another language or that the locale restriction is required for a documented region-specific purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The constant DEFAULT_ANALYSIS_TEXT is set to a Chinese phrase, which constrains the skill's natural-language behavior to a specific language by default. The file does not provide a user choice of language or explain that a Chinese-only mode is required.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.