T03 · Remote Payload Retrieval and Execution
- Location
scripts/install.py:129- Finding
Mutable Remote Executable Downloaded and Executed Without Integrity Verification
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This hotel-booking skill has a coherent purpose, but it installs and runs mutable external software while handling real bookings and personal data, so it needs review before installation.
Install only if you trust the RollingGo npm package and GitHub release channel. Avoid running the installer with administrator privileges, review any update before applying it, and be aware that the skill can submit real hotel orders and expose booking history, names, email addresses, and payment links through its CLI workflow.
scripts/install.py:129Mutable Remote Executable Downloaded and Executed Without Integrity Verification
scripts/install.py:20Unpinned Package Installed Globally Through npm
scripts/rgh.js:22Windows Shell Invocation Permits Command Injection Through Forwarded Arguments
The manifest presents the skill as a hotel search/booking assistant, but the instructions also require installing software, downloading binaries, modifying the local filesystem, and changing execution flow based on tool versioning. This mismatch increases the chance that users or orchestrators grant trust appropriate for a booking skill while the skill performs privileged system-management actions.
Referenced artifact was not completely inspected
> - **每日检查**:若当前目录下的 `.version_check` 不存在或记录日期非今天,静默请求远端 `SKILL.md`(地址拼接规则:将元数据中的 `{repository}` 域名替换为 `raw.githubusercontent.com`,并在末尾追加 `/main/skills/{name}/S
The skill declares no explicit tool scope while instructing use of shell commands, network access, environment handling, file writes, and local installation flows. This weakens least-privilege boundaries and can let an agent invoke broader capabilities than users would reasonably expect from a hotel-booking skill.
The description-level trigger list includes generic phrases like lodging-related terms that may appear in normal conversation without clear intent to use this skill. Because the skill can progress into network operations and commerce-related steps, ambiguous activation raises the risk of unintended actions and unnecessary exposure of account-linked flows.
The file is written entirely in Chinese and prescribes fixed Chinese response phrases and templates, but it does not state that the skill is China-only or that users may choose another language. This can violate language/locale policy when used in broader environments because it imposes a language without opt-in.
The update instruction uses an unpinned 'npx skills' invocation, which can fetch and execute whatever package version is current at runtime. That creates a software supply-chain risk: a compromised upstream package or unexpected breaking release could run arbitrary code in the agent environment.
The trigger scope is broad enough to activate on ordinary travel or lodging conversation, increasing the chance the skill runs when the user did not intend to invoke a hotel-booking workflow. In this skill, accidental activation is more dangerous because invocation can lead to login prompts, network calls, software installation, and eventually real purchase flows.
This markdown section documents book as accepting email and guest identity details, which are user-sensitive data used to create a formal order. The description does not include any warning that this information will be transmitted to an external booking service or used to place a real reservation.
This section states that the command returns all historical hotel orders and includes personally identifiable information such as contact names and email addresses. The documentation lacks any warning that invoking this command reveals sensitive booking history and personal data.
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 globally via npm!")
return True
print("⚠️ npm global installation failed (might need administrator/sudo permissions).")
print(stderr)
return False
The installer retrieves release metadata from GitHub and then downloads an executable for local use, but it performs no cryptographic signature or checksum verification on the fetched artifact. If the release channel, repository, network trust boundary, or upstream account is compromised, the script could install and later execute a malicious binary, which is especially dangerous in an installer context.
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 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
The manifest describes a hotel search and booking assistant that calls RollingGo hotel service APIs, but this file implements generic subprocess execution by spawning an external rgh program and forwarding all user-provided CLI arguments to it. Launching local executables is a stronger capability than direct API access and is not explicitly justified by the manifest text.
The wrapper forwards arbitrary command-line arguments directly to an external command and, on Windows fallback, may invoke it through a shell. Although the skill appears intended to call its own hotel CLI, there is no validation, allowlist, or user disclosure about what arguments are accepted, which increases the risk of abuse, unexpected side effects, or shell-mediated argument misinterpretation in hostile execution environments.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
args = [target_cmd] + sys.argv[1:]
try:
use_shell = is_win and target_cmd.endswith(".cmd")
res = subprocess.run(args, shell=use_shell)
sys.exit(res.returncode)
except KeyboardInterrupt:
sys.exit(130)
The skill instructs the agent to perform a daily remote fetch of SKILL.md and write a local marker file regardless of immediate booking needs. This introduces unnecessary network and filesystem side effects, expands attack surface, and creates a covert persistence/update-check mechanism unrelated to the core user task.
The file contains natural-language content in Chinese, including comments and user-facing error messages, without indicating that the skill is Chinese-only or giving users a language/locale option. Per the policy, forcing a specific language without opt-in can be a locale-policy violation.
Detected: suspicious.dangerous_exec