Back to skill

Security audit

酒店竞对调研openclaw助手

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a basic hotel report generator, but its advertised automatic hotel-search capability is not implemented and it has avoidable input-handling and dependency risks.

Review this before installing if you need real automatic competitor discovery: the packaged script does not implement that feature. If used anyway, run it only on trusted Excel files or manually entered data, review generated Markdown before sharing, and consider pinning/removing dependencies before installation.

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/hotel_analysis.py:73
Finding
Unescaped User-Controlled Data Injected into Generated Markdown Reports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/hotel_analysis.py:73-93` **Additional Input Source**: `scripts/hotel_analysis.py:153-164` **Vulnerability Type**: Markdown content injection **Risk Level**: Medium ### Vulnerable Code ```python # Target hotel report.append("## Target Hotel") report.append("") report.append(f"- **Name**: {self.hotel_name}") report.append("") # Competitor list report.append("## Competitors (Manually Entered)") report.append("") if self.competitors: report.append("| Hotel Name | Distance | Rating | Price |") report.append("|------------|----------|--------|-------|") for comp in self.competitors: name = comp.get('name', '-') distance = comp.get('distance', '-') rating = comp.get('rating', '-') price = comp.get('price', '-') report.append(f"| {name} | {distance} | {rating} | {price} |") ``` The original source contains Chinese report labels, but the vulnerable interpolation operations are: ```python report.append(f"- **名称**: {self.hotel_name}") report.append(f"| {name} | {distance} | {rating} | {price} |") ``` The values can be supplied through command-line arguments or an Excel workbook: ```python if args.competitors: separators = [',', ',', ';', ';', '、'] comps = args.competitors for sep in separators: comps = comps.replace(sep, ',') comp_list = [c.strip() for c in comps.split(',') if c.strip()] for comp in comp_list: analysis.add_competitor(comp) if args.input: try: import pandas as pd df = pd.read_excel(args.input) for _, row in df.iterrows(): analysis.add_competitor( name=row.get('酒店名称'), distance=row.get('距离'), rating=row.get('评分'), price=row.get('价格区间') ) ``` ### Technical Analysis The hotel name and competitor fields are inserted directly into Markdown without escaping or normalization. The applic ...[truncated 1986 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Escape all untrusted fields before inserting them into Markdown: - Escape backslashes, pipes, brackets, parentheses, asterisks, underscores, angle brackets, and other Markdown control characters. - Replace carriage returns and line feeds with spaces. - Encode or reject raw HTML delimiters. 2. Validate each imported field: - Require hotel names to be strings. - Enforce reasonable maximum lengths. - Require ratings and prices to have expected numeric formats. - Normalize distance values rather than retaining arbitrary text. 3. Use a dedicated Markdown-escaping function for every dynamic value. 4. If reports are rendered in an application, disable raw HTML and remote-resource loading where possible. 5. Treat imported Excel files as untrusted input and reject cells containing control characters or unsupported data types. 6. Add tests covering table delimiters, embedded links, image syntax, HTML, and multiline input. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Unpinned and Unnecessary Third-Party Dependencies Increase Supply-Chain Exposure<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-5` **Vulnerability Type**: Unbounded dependency resolution and unnecessary dependency installation **Risk Level**: Low ### Vulnerable Code ```text requests>=2.28.0 pandas>=1.5.0 openpyxl>=3.0.0 pyyaml>=6.0 argparse>=1.4.0 ``` ### Technical Analysis All declared packages use open-ended minimum-version constraints. Consequently, two installations performed at different times can resolve to materially different package versions without any review or source change in this project. The file also contains no integrity hashes. The implementation only imports `pandas` for optional Excel processing and otherwise relies on Python standard-library modules. `requests` and `pyyaml` are not used by the reviewed script. Python 3 already supplies the `argparse` module in its standard library, making installation of a separate `argparse` distribution unnecessary for this program. Installing unused packages expands the number of package archives and installation processes that must be trusted. Open-ended constraints also allow a future compromised or maliciously modified release satisfying the minimum version to be selected automatically. No evidence was found that the currently named packages are malicious. The finding concerns unsafe dependency-management practices and the resulting avoidable supply-chain exposure. ### Attack Path 1. A user or deployment pipeline executes `pip install -r requirements.txt`. 2. The package resolver selects any available versions that satisfy the open-ended `>=` constraints. 3. A newly published, compromised, or otherwise unsafe package version can be selected without a corresponding project change or security review. 4. Package installation code executes with the privileges of the user or build environment performing the installation. 5. Malicious installation behavior could access files, credentials, or build artifacts available to that environment. ### Impact ...[truncated 616 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove dependencies not used by the implementation, including `requests`, `pyyaml`, and the third-party `argparse` package unless another documented component requires them. 2. Retain only the dependencies required for supported functionality, such as reviewed versions of `pandas` and `openpyxl` for Excel import. 3. Pin every direct and transitive dependency to an explicitly reviewed version. 4. Generate a lock file or hash-locked requirements file using a dependency-management tool such as `pip-tools`. 5. Install packages with hash verification, for example through `pip install --require-hashes`. 6. Use automated vulnerability and update monitoring while requiring review before dependency upgrades. 7. Separate optional Excel dependencies from the minimal runtime dependencies so users who do not need Excel import do not install the additional package surface. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description promises automatic nearby-hotel discovery and report generation, but the reported implementation does not actually perform that workflow and includes a non-functional auto-fetch path. This mismatch is dangerous because users and orchestrators may make trust and execution decisions based on false capability claims, leading to silent failures, misleading analysis, or unsafe assumptions about external data collection.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The README presents all user-facing instructions in Chinese and does not indicate that the skill is region-specific or provide any opt-in for language selection. This can violate language/locale policy when users are not given a choice or informed of the restriction.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises executable behavior with file-writing capability but does not declare any tool scope such as permissions or allowed-tools. That creates an authorization and transparency gap: a host system or user cannot easily determine what the skill is permitted to do, increasing the risk of unintended file modification or abuse if the implementation writes reports or other artifacts.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The natural-language description and instructions are entirely in Chinese, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific audience. The policy requires flagging language or locale constraints when they are imposed without user opt-in or clear justification.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest describes a skill that 'automatically searches nearby hotels' and generates a competitive analysis report. In this implementation, the CLI accepts manually provided competitors or imports them from Excel, while the '--auto-fetch' path only prints that API configuration is required and does not perform any search. This is a substantive mismatch between the advertised capability and the actual code behavior.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The skill description omits a clear warning that it may query an external map service API for nearby-hotel data. This is a transparency and privacy issue because users may not realize that their hotel name, location context, or usage patterns could be sent to a third party.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
pandas>=1.5.0
openpyxl>=3.0.0
pyyaml>=6.0
Confidence
95% confidence
Finding
The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time. This weakens build reproducibility and can unintentionally introduce vulnerable or breaking releases into the skill's environment.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
92% confidence
Finding
The manifest does not pin requests, so it is impossible to verify from this file whether deployment will use a version affected by known advisories. Because requests handles outbound HTTP traffic and may interact with credentials, ambiguity around its installed version creates avoidable supply-chain and runtime risk.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
pandas>=1.5.0
openpyxl>=3.0.0
pyyaml>=6.0
argparse>=1.4.0
Confidence
95% confidence
Finding
Using an unpinned pandas version means installations are not reproducible and may pull in newer releases with security or compatibility issues. In security-sensitive workflows, this increases supply-chain uncertainty even if no exploit is present in the file itself.

Unverifiable Dependency: pandas has 1 known advisory(ies) (CVE-2020-13091 (** DISPUTED ** pandas through 1.0.3 can unserialize and execute commands from an)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding
Because pandas is not pinned, the security posture of the installed environment cannot be validated from the manifest alone. This is a weaker issue than active vulnerable code, but it still undermines assurance and reproducibility.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
pandas>=1.5.0
openpyxl>=3.0.0
pyyaml>=6.0
argparse>=1.4.0
Confidence
95% confidence
Finding
An unpinned openpyxl dependency can resolve to different versions across environments, making it hard to verify whether known vulnerable releases are excluded. This is especially relevant for libraries that process complex file formats such as spreadsheets.

Unverifiable Dependency: openpyxl has 2 known advisory(ies) (CVE-2017-5992 (Improper Restriction of XML External Entity Reference in Openpyxl); CVE-2017-5992 (Openpyxl 2.4.1 resolves external entities by default, which allows remote attack)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
The requirements file does not establish which openpyxl version will be installed, so known vulnerable historical releases cannot be ruled out. Since openpyxl processes spreadsheet content, inability to verify patch level is a meaningful but low-severity dependency management risk.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
pandas>=1.5.0
openpyxl>=3.0.0
pyyaml>=6.0
argparse>=1.4.0

# Optional dependencies
Confidence
97% confidence
Finding
PyYAML has a history of unsafe deserialization issues, and leaving it unpinned makes it unclear which behavior and security fixes will be present at install time. In a skill ecosystem, YAML is commonly used for configuration, so version drift can materially increase risk if unsafe loading is used elsewhere in the project.

Unverifiable Dependency: pyyaml has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding
PyYAML has multiple past advisories involving unsafe parsing behavior, and the unpinned manifest prevents confirmation that only patched versions will be installed. Given the common use of YAML for configuration in skills, this uncertainty is more concerning than for a purely auxiliary package.

Unpinned Dependencies

Low
Category
Supply Chain
Content
pandas>=1.5.0
openpyxl>=3.0.0
pyyaml>=6.0
argparse>=1.4.0

# Optional dependencies
# scrapling>=1.0.0  # For OTA scraping (advanced mode)
Confidence
50% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Static analysis

No suspicious patterns detected.