Back to skill

Security audit

RollingGo全球酒店预订Skill-新版本1.1.1

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed hotel-booking assistant, but its installer and update flow rely on mutable executable downloads and unpinned latest packages while handling real bookings and personal data.

Install only if you trust RollingGo and are comfortable with a CLI that can log in through OAuth, view hotel orders, create payable reservations after confirmation, and process your name and email. Prefer a pinned, verified release or a platform-managed install before using this in a sensitive environment, and review booking details carefully before confirming any order.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install.py:134
Finding

Mutable Remote Executable Is Downloaded and Made Executable Without Integrity Verification

Content
View full analysis

Vulnerability Details

File Location: scripts/install.py:34-54, 134-167
Vulnerability Type: Remote payload retrieval and execution
Risk Level: High

Complete Code Snippet

python
def download_binary(url, dest_path):
    """Download a file from url to dest_path with progress indication."""
    print(f"Downloading binary from: {url}")
    print(f"Saving to: {dest_path}")

    req = urllib.request.Request(
        url,
        headers={'User-Agent': 'RollingGo-Installer/1.0'}
    )

    try:
        with urllib.request.urlopen(req) as response:
            with open(dest_path, 'wb') as out_file:
                shutil_copy(response, out_file)
        print("✅ Download completed successfully!")
        return True
    except Exception as e:
        print(f"❌ Download failed: {e}")
        return False
python
# Try fetching from GitHub API
assets, tag = get_latest_release_assets()
download_url = None

if assets:
    for asset in assets:
        name = asset.get('name', '').lower()
        # Match keywords (e.g. 'win' or 'windows' for Windows, 'macos' for Mac, 'linux' for Linux)
        if asset_keyword in name:
            download_url = asset.get('browser_download_url')
            print(f"Found matching asset for version {tag}: {asset.get('name')}")
            break

# Fallback to hardcoded URL patterns if API fails or asset not found
if not download_url:
    print("Using hardcoded fallback download URL...")
    if system == "windows":
        download_url = "https://github.com/RollingGo-AI/oauth-hotel-cli/releases/latest/download/rgh-win.exe"
    elif system == "darwin":
        download_url = "https://github.com/RollingGo-AI/oauth-hotel-cli/releases/latest/download/rgh-macos"
    else:
        download_url = "https://github.com/RollingGo-AI/oauth-hotel-cli/releases/latest/download/rgh-linux"

success = download_binary(download_url, dest_path)

...[truncated 3397 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin the installer to a specific audited release version rather than using latest.
  2. Bundle expected SHA-256 or stronger digests for every supported operating-system and architecture artifact.
  3. Verify the digest before assigning executable permissions or moving the file into the final bin directory.
  4. Prefer cryptographically signed releases and verify signatures against a trusted public key bundled with the reviewed Skill.
  5. Store release metadata and checksums in a separately protected, versioned channel so compromise of the binary publication path alone is insufficient.
  6. Map exact asset names to supported operating-system and CPU architecture combinations; reject unexpected or ambiguous assets.
  7. Download into a securely created temporary file, enforce a reasonable size limit, verify it, and then atomically rename it into place.
  8. Reject unexpected redirects or validate that the final response URL belongs to an explicitly approved GitHub release-asset domain.
  9. Require explicit user approval before replacing an existing executable.
  10. Remove the mandatory automatic-upgrade rule in SKILL.md:62; updates should be pinned, reviewed, integrity-checked, and user-approved.

T08 · Insecure Dependencies

Error
Location
scripts/install.py:18
Finding

Unpinned npm Package Is Installed Globally

Content
View full analysis

Vulnerability Details

File Location: scripts/install.py:18-32
Vulnerability Type: Insecure third-party dependency installation
Risk Level: High

Complete Code Snippet

python
def install_via_npm():
    """Attempt to install @rollinggo/hotel via npm."""
    print("Checking npm environment...")
    npm_cmd = "npm.cmd" if platform.system() == "Windows" else "npm"

    # Try global installation
    print("Attempting to install @rollinggo/hotel globally via npm...")
    code, stdout, stderr = run_command([npm_cmd, "install", "-g", "@rollinggo/hotel@latest"])
    if code == 0:
        print("✅ Successfully installed @rollinggo/hotel globally via npm!")
        return True

    print("⚠️ npm global installation failed (might need administrator/sudo permissions).")
    print(stderr)
    return False

Technical Analysis

The installer requests @rollinggo/hotel@latest, so the effective dependency can change after the Skill has been reviewed. npm installation can execute package lifecycle scripts, meaning code from the selected package version may run during installation rather than only when the resulting CLI is invoked.

The -g option installs the package globally instead of confining it to the Skill directory. This broadens the package's effect on the user's command environment and may replace or expose an rgh command for unrelated sessions. A Skill-local installation is sufficient for the declared functionality and would better follow least-privilege principles.

The package version and integrity value are not pinned in the Skill. Although npm registry metadata normally includes integrity information for a resolved package, selecting the mutable latest distribution tag does not guarantee that the installed version is the one reviewed by the Skill author or auditor.

Attack Path

  1. An attacker compromises the npm publisher account, publication token, package repository, or rel ...[truncated 1222 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin an explicitly audited package version instead of using @latest.
  2. Maintain and verify a lockfile containing the exact package resolution and registry integrity hash.
  3. Install the dependency in a Skill-local directory rather than using npm install -g.
  4. Invoke the local binary through an exact path so it cannot replace or be confused with unrelated global tools.
  5. Where feasible, install with lifecycle scripts disabled and only enable a reviewed build step when strictly required.
  6. Document the package version and expected integrity value in the reviewed Skill release.
  7. Require explicit user confirmation before installing or updating executable dependencies.
  8. Do not recommend administrator or sudo execution when global installation fails; fall back to a verified local installation.
  9. Periodically audit the package's transitive dependencies and publication controls.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose is hotel search/booking, but the skill also instructs software installation, binary downloading, filesystem modification, and execution of local programs. This mismatch is dangerous because users and hosting platforms may grant trust appropriate for a travel assistant, while the skill actually expands into system-changing behavior with materially higher risk.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
> - **每日检查**:若当前目录下的 `.version_check` 不存在或记录日期非今天,静默请求远端 `SKILL.md`(地址拼接规则:将元数据中的 `{repository}` 域名替换为 `raw.githubusercontent.com`,并在末尾追加 `/main/skills/{name}/S

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases and user prompt examples are broad and map to common travel-related speech, increasing the chance that an agent invokes booking-related behavior when the user only wants advice or exploration. In this skill's context, unintended activation is more dangerous because the workflow can progress toward real-world reservations and payment links.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The README instructs users to execute npx skills add ... without pinning a specific package version. Because npx resolves and executes the latest published package by default, a compromised upstream release or dependency substitution could result in arbitrary code execution during installation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This installation example again relies on unpinned npx skills, which causes execution of whatever current version is returned by the package registry. In a skill ecosystem that directly influences agent behavior and may install tooling, that creates a meaningful software supply-chain risk.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The command uses npx skills without version pinning, exposing users to execution of an unreviewed future package version. Since installation is presented as the recommended path, the attack surface is amplified if the upstream package or its dependencies are ever compromised.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The user confirmation prompt asks specifically for the guest’s “中文姓名拼音(或英文名),” which imposes a locale-specific naming convention in the booking flow. The document does not present this as an optional locale preference or clearly justify it as a region-specific requirement at that point in the flow.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation explicitly instructs agents to '绝对不要向用户泄露原始的 hotelId 或 referenceNo' / 'Never leak hotelId or referenceNo directly to the user'. However, the same README repeatedly shows these raw identifiers in command examples and outputs, including hotelId in hotel search/detail flows and referenceNo in price-confirm output, undermining the stated intent and guidance.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The instruction tells agents to use rgh commands whenever the user asks to book a hotel, search rooms, or check orders, without enough guardrails around ambiguity, account context, or user authorization. Because the skill interacts with a real transaction system, broad activation can lead to privacy exposure (orders) or unintended progression toward a booking flow.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The English section repeats the same unpinned npx skills installation pattern. That duplicates the supply-chain exposure across multiple user paths and increases the chance that users execute a mutable installer command.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

This command snippet is another floating npx skills invocation, which trusts the current registry state at execution time. If an attacker publishes or compromises a dependency in that path, users may run attacker-controlled code locally.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The direct skill installation example executes an unpinned installer via npx, making the exact code path non-deterministic over time. That is a classic dependency/supply-chain weakness, especially risky for documentation that encourages immediate execution.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The --agent cursor example still depends on the same unpinned npx skills execution path. The agent-specific variant does not reduce the underlying registry-based code execution risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes shell commands and performs networked operations, but it does not declare explicit tool permissions or allowed-tools boundaries. In an agent environment, this increases the chance of unintended command execution or network access beyond what a hotel-booking workflow minimally requires.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest description lists many trigger phrases such as “入住”, “住哪”, “住宿”, and broad travel-related terms that can appear in ordinary conversation without a clear intent to use this specific hotel-booking skill. Although examples and a 'When NOT to Use' section exist elsewhere, the trigger list itself remains expansive enough to overlap with common speech and may cause accidental activation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill adds autonomous version checks against a remote repository and writes a local .version_check file daily, which is unrelated to the core booking task. Unnecessary background network access and local file writes increase attack surface and can be abused for persistence-like state changes or silent remote influence over skill behavior.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding

The update instruction uses an unpinned npx package invocation, which can fetch and execute whatever version is current at runtime. This creates a supply-chain risk where a compromised or breaking upstream release could be executed automatically in a privileged agent context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The installation guidance tells the agent or operator to install npm packages, run a Python installer, or download standalone binaries from GitHub releases. For a hotel-booking skill, these actions are not intrinsic to the business task and introduce substantial supply-chain and code-execution risk if the package, script, or release artifact is compromised.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The instructions are written as mandatory output rules in Chinese and do not indicate that the assistant should adapt to the user's preferred language or locale. This creates a language-policy concern because the skill appears to enforce a specific language/locale behavior without user opt-in or documented regional justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file describes the book operation collecting --first-name, --last-name, and --email to create a formal hotel order, but it does not include any warning that this personal data will be sent to an external booking system. For markdown files, SQP-2 applies when behaviors affecting user data or privacy are described without disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The orders section states it retrieves all historical hotel orders and returns contact name and email fields, which are sensitive personal and transaction data. The markdown does not warn users that invoking this command reveals prior booking history and associated personal information.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/install.py (reported line 13)May include surrounding context.

python
def run_command(args):
    """Run a system command and return exit code and output."""
    try:
        result = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        return result.returncode, result.stdout, result.stderr
    except Exception as e:
        return -1, "", str(e)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/install.py (reported line 30)May include surrounding context.

python
print("✅ Successfully installed @rollinggo/hotel globally via npm!")
        return True
    
    print("⚠️ npm global installation failed (might need administrator/sudo permissions).")
    print(stderr)
    return False

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/install.py (reported line 65)May include surrounding context.

python
def get_latest_release_assets():
    """Query GitHub API for the latest release assets."""
    api_url = "https://api.github.com/repos/RollingGo-AI/oauth-hotel-cli/releases/latest"
    req = urllib.request.Request(
        api_url,
        headers={'User-Agent': 'RollingGo-Installer/1.0'}

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/install.py (reported line 87)May include surrounding context.

python
# Check if node and npm are available
    has_node = False
    try:
        node_code = subprocess.call(["node", "--version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        npm_code = subprocess.call(["npm" if platform.system() != "Windows" else "npm.cmd", "--version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        has_node = (node_code == 0 and npm_code == 0)
    except Exception:

Static analysis

No suspicious patterns detected.