Back to skill

Security audit

Travel Information and News

Security checks for vulnerabilities and agentic risk

Overview

The skill is a travel-search tool, but its optional browser scraping and install guidance create review-worthy security and privacy risk.

Review before installing, especially if you would enable browser scraping. Use a throwaway, isolated environment with no unrelated secrets, avoid installing desktop-control unless truly needed, pin dependencies, and do not submit sensitive travel or account information as search queries.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/browser_search.js:89
Finding

Chromium Browser Sandbox Is Explicitly Disabled

Content
View full analysis

Vulnerability Details

File Location: scripts/browser_search.js:89-94
Vulnerability Type: Chromium sandbox disabled while processing untrusted websites
Risk Level: High

Complete Code Snippet:

javascript
const browser = await puppeteer.launch({
  headless: true,
  executablePath: "/usr/bin/chromium",
  args: ["--no-sandbox", "--disable-gpu", "--disable-dev-shm-usage"],
});

Technical Analysis

The browser automation launches Chromium with the --no-sandbox argument. Browser search visits public websites and processes remotely controlled HTML, JavaScript, media, and other content. Chromium's sandbox is a major defense-in-depth boundary intended to contain a compromised renderer or browser process.

Disabling this boundary is not necessary for the declared search functionality. It materially increases the consequences of a Chromium or Puppeteer vulnerability because malicious web content may be able to escape the browser process and access resources available to the operating-system account running the Skill.

The use of a fixed user agent does not provide a security boundary. Running Chromium in headless mode also does not compensate for disabling the sandbox.

Attack Path

  1. A user invokes the Skill with the optional --use_browser mode.
  2. The Python entry point starts this Puppeteer script.
  3. Chromium visits Xiaohongshu and X/Twitter and processes content controlled by those platforms, advertisers, embedded third parties, or compromised accounts.
  4. Malicious content exploits a Chromium vulnerability.
  5. Because Chromium was launched with --no-sandbox, an important containment layer is unavailable.
  6. The attacker may execute code or access data with the permissions of the Skill's operating-system account.

Impact Assessment

Successful exploitation could expose files, environment variables, API credentials, network access, and other resources available to the Skill pr ...[truncated 210 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the --no-sandbox argument and run Chromium with its normal sandbox enabled.
  • Execute browser automation as a dedicated, unprivileged operating-system user.
  • Do not run the browser as root.
  • If the Chromium sandbox cannot be enabled, run browser automation inside a disposable, hardened container or virtual machine.
  • Give that isolation environment a read-only filesystem where possible, no host-sensitive mounts, no inherited credentials, limited memory and CPU, and a restricted outbound network policy.
  • Keep Chromium and Puppeteer patched and use compatible, reviewed versions.
  • Treat all browser results as untrusted data and avoid executing or interpreting returned content as code.

T08 · Insecure Dependencies

Warning
Location
README.md:51
Finding

Unpinned Third-Party Packages and High-Privilege Skill Installation

Content
View full analysis

Vulnerability Details

File Location: README.md:51, README.md:77-84, SKILL.md:45, and SKILL.md:54
Vulnerability Type: Mutable and insufficiently verified dependency installation
Risk Level: Medium

Complete Code Snippets:

bash
pip install requests fpdf2 python-docx
bash
npm install puppeteer
bash
npx clawhub install desktop-control

Technical Analysis

The installation instructions do not pin exact dependency versions or verify artifact integrity. Consequently, package managers resolve mutable versions at installation time, and the code ultimately installed can differ from the code considered during this audit.

Python and npm packages can execute attacker-controlled logic during installation or when imported. The npx-based installation path also introduces dynamically resolved package and Skill content. A compromised publisher account, malicious future release, dependency confusion event, registry compromise, or compromised transitive dependency could therefore introduce arbitrary code.

The optional desktop-control Skill is especially sensitive because mouse, keyboard, and screen automation grant substantially broader capabilities than ordinary travel search. Installing it globally or in a shared Agent environment would expand the attack surface beyond the minimum privileges required by this project's implemented browser search.

Attack Path

  1. An operator follows the documented setup commands.
  2. The package manager resolves the latest compatible package or Skill artifacts because no exact versions and integrity hashes are specified.
  3. A package, transitive dependency, publisher account, registry entry, or Skill release is compromised.
  4. Malicious lifecycle code executes during installation, or malicious module code executes when imported.
  5. The payload gains the permissions of the user running pip, npm, or npx.
  6. If desktop-control is com ...[truncated 598 chars]
Remediation
View remediation

Remediation Suggestions

  • Pin every direct dependency to an exact reviewed version.
  • Provide a committed Python requirements file with hashes and install it using pip --require-hashes.
  • Provide a committed npm lockfile and use npm ci rather than an unconstrained npm install.
  • Review and lock transitive dependencies as part of release preparation.
  • Use trusted registries and enable package provenance or signature verification where supported.
  • Avoid dynamically installing Skills through an unpinned npx command.
  • If desktop-control is genuinely required, pin a reviewed release, verify its integrity, document why its privileges are necessary, and install it only in an isolated environment.
  • Remove the desktop-control recommendation if ordinary Puppeteer navigation is sufficient.
  • Run dependency installation as an unprivileged user and separate build-time credentials from runtime credentials.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/search.py:141
Finding

Browser Subprocess Inherits the Entire Environment Including Unneeded Secrets

Content
View full analysis

Vulnerability Details

File Location: scripts/search.py:141-147
Vulnerability Type: Excessive propagation of environment variables to browser automation
Risk Level: Medium

Complete Code Snippet:

python
try:
    result = subprocess.run(
        ["node", browser_script, "--query", query],
        env={**os.environ, "DISPLAY": ":99"},
        capture_output=True, text=True, timeout=60
    )

Technical Analysis

The browser subprocess receives a copy of the complete parent environment. Earlier in the same program, values from .env files are imported into os.environ. The inherited environment can therefore include TAVILY_API_KEY, BRAVE_API_KEY, and unrelated credentials supplied by the host.

The Node browser helper does not require these API keys to search Xiaohongshu or X/Twitter. Passing all environment variables violates least privilege and unnecessarily exposes secrets to Node.js, Puppeteer, Chromium descendants, and any compromised dependency loaded in that process.

The current browser helper does not explicitly transmit these credentials. The risk arises from avoidable secret availability: a compromised dependency, future code change, debugger, crash handler, or browser exploit could read and exfiltrate inherited values using the subprocess's network access.

Attack Path

  1. The parent process starts with sensitive values in its environment or loads values from a project or working-directory .env file.
  2. A user enables browser search.
  3. subprocess.run copies the complete environment into the Node.js process.
  4. Node.js dependencies and descendant processes can read all inherited values.
  5. A compromised Puppeteer dependency, malicious future modification, or successful browser-process exploit reads the unnecessary credentials.
  6. The attacker transmits the credentials through the available outbound network connection and uses them against the corresponding services ...[truncated 429 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace complete environment inheritance with a strict allowlist containing only variables required by the browser helper.
  • Construct a minimal environment such as PATH, HOME, locale variables, and DISPLAY.
  • Explicitly exclude TAVILY_API_KEY, BRAVE_API_KEY, and all unrelated application credentials.
  • Run browser automation in a separate, secret-free service account or isolated container.
  • Restrict outbound networking from browser automation to the specific destinations required by the feature.
  • Avoid loading arbitrary keys from .env; parse only explicitly supported configuration names.
  • Add automated tests confirming that API keys and representative unrelated secrets are absent from the Node.js subprocess environment.
  • Document which data is transmitted to Tavily, Brave, Xiaohongshu, and X/Twitter so users can avoid submitting sensitive search terms.
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 (26)

Tainted flow: 'api_key' from os.getenv (line 85, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/search.py (reported line 49)May include surrounding context.

python
return []

    try:
        resp = requests.post(
            "https://api.tavily.com/search",
            headers={"Authorization": f"Bearer {api_key}"},
            json={

Tainted flow: 'api_key' from os.getenv (line 85, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/search.py (reported line 91)May include surrounding context.

python
try:
        import requests
        resp = requests.get(
            "https://api.search.brave.com/res/v1/web/search",
            headers={"X-Subscription-Token": api_key, "Accept": "application/json"},
            params={"q": query, "count": count},

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 56)May include surrounding context.

Quick Start

bash
# Required: TAVILY_API_KEY in env or ~/.openclaw/.env
# Optional: BRAVE_API_KEY for Brave Search fallback

python scripts/search.py --query "Tokyo travel March 2026" --format text

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

Quick Start

bash
# Required: TAVILY_API_KEY in env or ~/.openclaw/.env
# Optional: BRAVE_API_KEY for Brave Search fallback

python scripts/search.py --query "Tokyo travel March 2026" --format text

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/search.py (reported line 17)May include surrounding context.

python
## Quick Start

```bash
# Required: TAVILY_API_KEY in env or ~/.openclaw/.env
# Optional: BRAVE_API_KEY for Brave Search fallback

python scripts/search.py --query "Tokyo travel March 2026" --format text

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/search.py (reported line 20)May include surrounding context.

python
# Load .env if available
def load_env():
    env_paths = [
        os.path.join(os.path.dirname(__file__), "..", ".env"),
        ".env",
    ]
    for path in env_paths:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/search.py (reported line 21)May include surrounding context.

python
# Load .env if available
def load_env():
    env_paths = [
        os.path.join(os.path.dirname(__file__), "..", ".env"),
        ".env",
    ]
    for path in env_paths:

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
97% confidence
Finding

The child Node process inherits the full parent environment, which may include TAVILY_API_KEY, BRAVE_API_KEY, and other unrelated secrets loaded from .env or the runtime. Any compromise, bug, or over-collection in browser_search.js or its dependencies could expose those credentials, making this a meaningful secret-spillage risk amplified by the browser automation context.

Content

Scanner excerpt · scripts/search.py (reported line 145)May include surrounding context.

python
try:
        result = subprocess.run(
            ["node", browser_script, "--query", query],
            env={**os.environ, "DISPLAY": ":99"},
            capture_output=True, text=True, timeout=60
        )
        if result.returncode == 0:

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · README.md (reported line 32)May include surrounding context.

md
- 🌐 **Multi-language** — Follows query language, switchable on demand
- 📄 **Multiple output formats** — Plain text, Word (docx), PDF (with CJK support)
- ⭐ **Review aggregation** — TripAdvisor and Google Maps ratings (ON by default, can be disabled)
- 🧹 **Deduplication** — Automatically removes duplicate results within each run
- 📅 **Time filtering** — 24h, week, month, year, or custom range

### Requirements

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README explicitly promotes scraping blocked sites and simulated clicking/pagination via browser automation, but does not clearly warn about site terms, privacy, consent, or legal/policy constraints. This can lead operators to collect data in ways that violate platform rules or expose personal/sensitive content, especially on social platforms.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding

The README instructs users to run npx clawhub install desktop-control without pinning an exact package/version. This creates a supply-chain risk because users may fetch a changed or compromised package at install time, especially since npx executes remote package code. The context increases risk slightly because the referenced skill provides desktop control and browser automation capabilities.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents capabilities that require environment access, file writing, network access, and shell execution, but it does not declare any explicit tool scope or permission boundaries. This increases the chance that an agent will invoke the skill with broader privileges than necessary, making misuse or unintended side effects harder to constrain and audit.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrase "anything travel-related" is overly broad and can cause the skill to activate for loosely related requests, including ones that do not require its higher-risk capabilities such as scraping, shell commands, or file output. Overbroad routing increases the attack surface by making it easier for unrelated prompts to access networked or browser-based behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill promotes browser scraping of third-party sites and anti-bot evasion behavior without a clear user-facing warning about privacy, terms-of-service, or compliance implications. This is dangerous because users or agents may collect personal data or access sites in ways that violate platform policies, creating legal, privacy, and operational risk.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

Using npx clawhub install desktop-control without pinning a specific version creates a supply-chain risk because the fetched package may change over time or be replaced by a malicious release. In a skill that already contemplates browser automation and shell usage, an unpinned install path materially increases the risk of executing untrusted code.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/search.py (reported line 49)May include surrounding context.

python
return []

    try:
        resp = requests.post(
            "https://api.tavily.com/search",
            headers={"Authorization": f"Bearer {api_key}"},
            json={

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/search.py (reported line 49)May include surrounding context.

python
return []

    try:
        resp = requests.post(
            "https://api.tavily.com/search",
            headers={"Authorization": f"Bearer {api_key}"},
            json={

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/search.py (reported line 50)May include surrounding context.

python
try:
        resp = requests.post(
            "https://api.tavily.com/search",
            headers={"Authorization": f"Bearer {api_key}"},
            json={
                "query": query,

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/search.py (reported line 92)May include surrounding context.

python
try:
        import requests
        resp = requests.get(
            "https://api.search.brave.com/res/v1/web/search",
            headers={"X-Subscription-Token": api_key, "Accept": "application/json"},
            params={"q": query, "count": count},
            timeout=30,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The browser-scraping mode materially expands capability by launching Xvfb, Node, and Puppeteer to load remote sites. In the context of a travel search skill, this larger execution surface increases risk from hostile web content, data leakage through child processes, and unexpected local resource access without strong isolation controls.

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/search.py (reported line 133)May include surrounding context.

python
# Ensure Xvfb is running
    import subprocess
    try:
        subprocess.run(["pgrep", "-f", "Xvfb :99"], capture_output=True, check=True)
    except subprocess.CalledProcessError:
        subprocess.Popen(
            ["Xvfb", ":99", "-screen", "0", "1200x720x24"],

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/search.py (reported line 135)May include surrounding context.

python
try:
        subprocess.run(["pgrep", "-f", "Xvfb :99"], capture_output=True, check=True)
    except subprocess.CalledProcessError:
        subprocess.Popen(
            ["Xvfb", ":99", "-screen", "0", "1200x720x24"],
            stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

The script launches a Node-based browser automation helper and passes the full inherited environment to it via env={**os.environ, 'DISPLAY': ':99'}. While the command itself is not shell-injected, executing an auxiliary script with all environment variables exposes API keys and other secrets to a larger execution surface, and the helper may fetch arbitrary remote content using a real browser stack.

Content

Scanner excerpt · scripts/search.py (reported line 143)May include surrounding context.

python
time.sleep(1)

    try:
        result = subprocess.run(
            ["node", browser_script, "--query", query],
            env={**os.environ, "DISPLAY": ":99"},
            capture_output=True, text=True, timeout=60

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The CLI help says '--language' is the output language, and the emitted note says the agent must translate all results to that language. In practice, the code only detects or records the language and prepends a reminder string; it does not translate search results or reformulate content into the requested language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The --language argument is optional, and when omitted the script defaults to detect_language(args.query). Because this detected value is later treated as the required output language, the skill imposes a language choice without an explicit user selection.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.