Back to skill

Security audit

Hormuz Strait Monitor

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real shipping-monitoring skill, but it should be reviewed because it downloads and runs browser-driver software at runtime and disables Chrome sandboxing while visiting external sites.

Install only if you are comfortable running a Selenium/Chrome automation script that downloads a browser driver at runtime and writes monitoring/debug files under your OpenClaw workspace. Prefer running it in an isolated virtual environment or container, pin dependencies and ChromeDriver, and avoid running it with broad host filesystem access or as root.

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)

T08 · Insecure Dependencies

Warning
Location
scripts/hormuz_monitor.py:34
Finding

Unpinned dependencies and runtime download of an executable browser driver

Content
View full analysis

Vulnerability Details

File Location: scripts/hormuz_monitor.py:34-70; related installation instructions at SKILL.md:84 and SKILL.md:127
Vulnerability Type: Supply-chain exposure through unpinned dependencies and runtime executable retrieval
Risk Level: Medium

Complete Code Snippet

python
try:
    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from webdriver_manager.chrome import ChromeDriverManager
except ImportError:
    print("ERROR: selenium and webdriver-manager not installed")
    print("Install: pip install selenium webdriver-manager")
    sys.exit(1)

def setup_driver():
    """Setup Chrome WebDriver with headless options"""
    options = Options()
    options.add_argument("--headless=new")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--disable-gpu")
    options.add_argument("--window-size=1920,1080")
    options.add_argument("--disable-extensions")
    options.add_argument("--disable-infobars")
    options.add_argument("--disable-notifications")
    options.add_argument("--lang=en-US")

    # Use installed Chrome
    options.binary_location = "/usr/bin/google-chrome"

    # Auto-download matching ChromeDriver
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=options)

    return driver

The documentation also instructs users to install dependencies without version or integrity constraints:

bash
pip install selenium webdriver-manager

Technical Analysis

The Skill does not pin exact versions or verify hashes for `seleniu ...[truncated 2337 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin exact dependency versions in a lock file or requirements file:
    text
    selenium==<reviewed-version>
    webdriver-manager==<reviewed-version>
    
  2. Require package hashes using a hash-locked installation process such as:
    bash
    pip install --require-hashes -r requirements.txt
    
  3. Remove runtime driver acquisition from the Skill. Provision a reviewed ChromeDriver through the deployment environment and reference its fixed local path.
  4. Verify the ChromeDriver version and cryptographic checksum before use.
  5. Store approved driver artifacts in a controlled internal repository rather than resolving them dynamically from public infrastructure.
  6. Run the Skill in a dedicated, unprivileged virtual environment or container with restricted filesystem and network access.
  7. Document the exact supported Chrome, ChromeDriver, Selenium, and Python versions.
  8. Fail closed if the approved local driver is missing or fails integrity verification instead of downloading a replacement automatically.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/hormuz_monitor.py:53
Finding

Chrome sandbox disabled while rendering remote JavaScript content

Content
View full analysis

Vulnerability Details

File Location: scripts/hormuz_monitor.py:53-58
Vulnerability Type: Unsafe browser isolation configuration
Risk Level: Medium

Complete Code Snippet

python
def setup_driver():
    """Setup Chrome WebDriver with headless options"""
    options = Options()
    options.add_argument("--headless=new")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")

Technical Analysis

The Skill intentionally visits two remote, JavaScript-heavy websites and executes their browser content. Passing --no-sandbox disables an important Chrome security boundary designed to isolate web-renderer processes from the host environment.

Remote page content is outside the Skill's trust boundary. Either monitored site, or a third-party script loaded by one of those sites, could be compromised and deliver malicious browser content. Browser sandboxing does not prevent all browser vulnerabilities, but it materially limits the consequences of many renderer compromises. Disabling it unnecessarily increases exposure and exceeds the minimum privileges needed for public shipping-data collection.

The option does not independently create arbitrary code execution. Exploitation would normally require a compatible Chrome vulnerability or another browser compromise. It increases the impact and reliability of such an attack by weakening containment.

Attack Path

  1. An attacker compromises hormuzstraitmonitor.com, shipxy.com, or a third-party resource loaded by either site.
  2. The compromised resource serves malicious JavaScript or browser content to the monitor.
  3. The Skill opens that content in Chrome using --no-sandbox.
  4. The malicious content exploits a compatible browser or renderer vulnerability.
  5. Because Chrome's sandbox is disabled, the compromised browser process has reduced isolation from the host environment.
  6. Attacker code may gain access ...[truncated 857 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the following argument:
    python
    options.add_argument("--no-sandbox")
    
  2. Run Chrome under a dedicated, non-root operating-system account.
  3. If the deployment environment cannot support Chrome's native sandbox, isolate the entire Skill in a hardened container or virtual machine with:
    • A read-only root filesystem.
    • No host filesystem mounts except a narrowly scoped output directory.
    • Dropped Linux capabilities.
    • no-new-privileges enabled.
    • Seccomp and mandatory access-control profiles.
    • Restricted outbound network access limited to required domains.
  4. Keep Chrome and ChromeDriver patched and version-compatible.
  5. Avoid running this Skill as root; do not treat --no-sandbox as a workaround for root execution.
  6. Consider separate browser sessions or containers for each remote source to reduce cross-site exposure.
  7. Apply execution timeouts and terminate the browser process if a source behaves unexpectedly.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (8)

Instruction Override

High
Category
Prompt Injection
Confidence
70% confidence
Finding

This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Content

Scanner excerpt · scripts/hormuz_monitor.py (reported line 605)May include surrounding context.

python
parser = argparse.ArgumentParser(description="Hormuz Strait Transit Monitor")
    parser.add_argument("--config", help="Path to config file")
    parser.add_argument("--channel", help="Notification channel (e.g., wecom, discord)")
    parser.add_argument("--debug", action="store_true", help="Enable debug mode (keep browser open)")
    args = parser.parse_args()
    
    # Load config

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documentation instructs users to run a Python script, install packages with pip, launch Chrome, access external websites, and append data to a CSV file, but the skill metadata does not declare any tool scope such as shell, file read, or file write permissions. This creates an undeclared capability boundary: an agent or user may execute filesystem and shell actions that are not transparently disclosed or constrained, increasing the risk of over-privileged execution and making review/auditing harder.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script downloads and installs ChromeDriver at runtime from the network, which expands the trust boundary and introduces a software supply-chain risk. In a sensitive agent environment, unpinned runtime installation can execute unexpected binaries if the dependency source is compromised or if a malicious version is resolved.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

On parsing failures, the script writes full screenshots and raw HTML from third-party sites to disk. Debug artifacts can capture more data than needed for the monitoring task, including page content, tokens, identifiers, or unexpected sensitive information shown in the browser session, and they persist locally without retention controls.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
55% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/hormuz_monitor.py (reported line 637)May include surrounding context.

python
"non_iranian_vessels": shipxy_data.get("non_iranian_vessels"),
        }
        
        # Load previous data for comparison
        previous = load_previous_data()
        
        # Check alerts

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The Chrome options hard-code --lang=en-US, which imposes a specific locale on all browsing sessions. This is a natural-language/locale policy concern because the skill does not offer any user choice or document why English-US is required.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest describes tracking transit data and alerting on recovery thresholds, but the code also appends historical data to a CSV on disk for ongoing storage. While related to monitoring, this local persistence is an additional operational behavior not stated in the manifest description.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The function documentation says it will send notifications through a channel, suggesting an external delivery action. In reality, the code just prints a channel label and the message, so the documentation overstates what the function does.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.