T08 · Insecure Dependencies
- Location
scripts/install.py:18- Finding
Unpinned and Unverified Executable Installation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a real hotel-search and booking assistant, but it should be reviewed carefully because it installs and auto-updates mutable executable code and can create real booking orders using OAuth-backed personal data.
Install only if you trust RollingGo's npm package and GitHub release process, and avoid letting an agent auto-update the CLI without your explicit approval. Confirm every booking step before order creation, and treat order history, names, authorization links, payment links, and travel dates as sensitive information.
scripts/install.py:18Unpinned and Unverified Executable Installation
The declared purpose is hotel search/booking, but the skill also performs software installation, binary download, file placement in PATH, permission changes, and upgrade orchestration. This description-behavior mismatch is dangerous because it can cause a user or agent to authorize broad system modifications under the pretense of a simple travel assistant.
The skill instructs the agent to inspect CLI output for update prompts and then automatically perform upgrades before continuing. Treating tool output as authoritative control input is dangerous because terminal output can influence agent behavior, leading to prompt/output-injection-driven execution of new install commands and potentially untrusted code.
After downloading, rename it to `rgg` (or `rgg.exe` on Windows), grant execution permissions, and place it in the system PATH or the skill directory's `bin` folder.
**⚠️ Auto-Update Interception Principle:**
The CLI tool has built-in version detection. When you execute any `rgg` command, if the console output prompts `📦 New version available!` or `Run the following command to update`, **you must immediately pause the current operation, use one of the above three methods to upgrade the tool to the latest version, and then re-execute the interrupted command.** This prevents booking failures due to expired server endpoints.
---
The skill requires both shell execution and network access but does not declare any explicit tool scope or permission boundary. In practice, this means an agent may run installation commands, invoke external CLIs, and contact remote services without a least-privilege contract, increasing the blast radius if the skill is triggered unexpectedly or modified upstream.
The trigger list contains broad everyday accommodation phrases, making accidental invocation more likely in unrelated conversations. Because the skill can initiate login, network calls, installation, and eventually booking-related actions, overbroad activation materially raises the chance of unintended side effects.
The skill instructs use of npx skills add ... without pinning a specific version, which allows execution of whatever package version is current at runtime. Combined with the version-check and update prompt behavior, this creates a supply-chain risk where an agent may fetch and execute unreviewed code from the network.
The instruction to trigger on any accommodation-related intent is ambiguous and expansive. In this skill's context, broad activation is riskier than normal because the workflow includes authentication handling, shell commands, external API usage, and a path toward real-money transactions.
The book command performs a real-world transaction step by creating an official order and returning a payment URL, but the description does not prominently warn that invoking it has side effects and can commit the user into a booking flow. In an agent setting, this increases the risk of unintended purchases or social-engineered bookings because a model or integrator may treat it like an informational lookup rather than an action requiring explicit user confirmation.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
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)
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
print("✅ Successfully installed @rollinggo/hotel-global globally via npm!")
return True
print("⚠️ npm global installation failed (might need administrator/sudo permissions).")
print(stderr)
return False
The installer fetches release metadata from GitHub and later downloads and installs an executable from network locations without any cryptographic verification, signature check, or pinned digest validation. If the release source is compromised, the network path is tampered with, or a malicious asset is published, the skill could install attacker-controlled code and then mark it executable.
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-overseas/releases/latest"
req = urllib.request.Request(
api_url,
headers={'User-Agent': 'RollingGo-Installer/1.0'}
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 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:
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
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:
has_node = False
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
---
> ⚠️ **Output Specifications**:
> 1. **DO NOT show any technical details to users**, including but not limited to: tool names (like `search-hotels`, `hotel-detail`), JSON field names (like `hotelId`, `ratePlanId`, `referenceNo`), command line contents, or technical parameters.
> 2. **ONLY show information users care about**: Hotel name, star rating, price, distance, core facilities, tags, and booking link.
> 3. **Results MUST be formatted properly**, with each hotel occupying a separate card. Key information should be separated by line breaks, and stacking them in a single line is prohibited.
> 4. **Price Description**: Prices in search results are reference prices for display purposes. The actual order price is subject to price confirmation, and it must be labeled as "Reference Price" when displayed.
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.
---
> ⚠️ **Output Specifications**:
> 1. **DO NOT show any technical details to users**, including but not limited to: tool names (like `search-hotels`, `hotel-detail`), JSON field names (like `hotelId`, `ratePlanId`, `referenceNo`), command line contents, or technical parameters.
> 2. **ONLY show information users care about**: Hotel name, star rating, price, distance, core facilities, tags, and booking link.
> 3. **Results MUST be formatted properly**, with each hotel occupying a separate card. Key information should be separated by line breaks, and stacking them in a single line is prohibited.
> 4. **Price Description**: Prices in search results are reference prices for display purposes. The actual order price is subject to price confirmation, and it must be labeled as "Reference Price" when displayed.
This rule uses Chinese locale terms ("景点", "城市") inside operational guidance without indicating that language or locale should follow the user's preference. In a global hotel-booking skill, embedding locale-specific terminology can create an implicit language/locale constraint not chosen by the user.
The orders command exposes historical booking data and contact details, including names, hotel addresses, order identifiers, and stay dates, but the documentation does not warn that this is sensitive personal data. In an agent ecosystem, lack of a privacy warning can lead to over-sharing, unnecessary retrieval, or accidental disclosure of user travel history and contact information.
No suspicious patterns detected.