Back to skill

Security audit

Spot

Security checks for vulnerabilities and agentic risk

Overview

This booking skill has a coherent purpose, but it needs Review because it combines account/session handling, background monitoring, self-updating code, and risky VPN/browser host controls.

Install only if you trust the publisher and are comfortable with booking automation that can store sessions, run scheduled monitors, alter local data files, route traffic through VPNs, and control browser processes. Disable or avoid spot.update unless updates are reviewed and pinned, prefer manual OAuth/login flows over sharing raw passwords, keep VNC/CDP bound to localhost, and run the VPN/browser pieces in a contained environment.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/reservation_toolkit.py:57
Finding
Untrusted Remote OpenVPN Configuration Is Executed Without Directive Validation## Vulnerability Details **File Location**: `scripts/reservation_toolkit.py`, lines 57–62 and 75–109 **Vulnerability Type**: Execution of remotely supplied active configuration **Risk Level**: High ### Vulnerable Code ```python def connect(self): if self.is_connected(): return subprocess.run(["pkill", "-f", "openvpn"], capture_output=True) time.sleep(2) if not Path(self.config_path).exists(): self._download_config() subprocess.run(["openvpn", "--config", self.config_path, "--daemon"], check=True) ``` ```python def _download_config(self): """Download best VPN Gate config with cipher fix.""" subprocess.run([ "curl", "-s", "https://www.vpngate.net/api/iphone/", "-o", "/tmp/vpn_list.csv" ], check=True) subprocess.run([ "python3", "-c", f""" import csv, base64 with open('/tmp/vpn_list.csv', newline='') as f: content = f.read() lines = content.split('\\n') data_lines = [l for l in lines if not l.startswith('*') and l.strip()] reader = csv.DictReader(data_lines) rows = list(reader) non_us = [r for r in rows if r.get('CountryShort','').strip() != 'US' and r.get('OpenVPN_ConfigData_Base64','').strip()] best = sorted(non_us, key=lambda s: int(s.get('Score',0)), reverse=True)[0] config = base64.b64decode(best['OpenVPN_ConfigData_Base64']).decode() if 'data-ciphers' not in config: lines2 = config.split('\\n') for i, line in enumerate(lines2): if line.startswith('cipher '): lines2.insert(i+1, 'data-ciphers AES-128-CBC:AES-256-GCM:AES-128-GCM') break config = '\\n'.join(lines2) with open('{self.config_path}', 'w') as f: f.write(config) print(f"Downloaded: {{best['CountryLong']}} {{best['IP']}}") """ ], capture_output=True, text=True, check=True) ``` ### Technical Analysis When a local VPN profile does not exist, the toolkit downloads a CSV feed from VPN Gate and selects a remotely supplied record based on its score and country. It Base6 ...[truncated 2275 chars]
Remediation
## Remediation Suggestions 1. **Do not execute arbitrary profiles from the public listing.** Use a fixed, administratively reviewed profile or a curated allowlist of trusted profile fingerprints and endpoints. 2. **Parse profiles using a strict directive allowlist.** Permit only the minimum connection directives required for the supported setup. Reject script hooks, plugins, management interfaces, file-output directives, privilege changes, and all unknown directives. 3. **Avoid text-only keyword filtering.** Parse OpenVPN syntax correctly, including inline blocks, quoting, continuation behavior, and directive aliases. 4. **Require explicit approval before first activation.** Display the selected endpoint and validated profile summary, then require confirmation before invoking OpenVPN. 5. **Apply least privilege and isolation.** Run the VPN client in a dedicated container or network namespace with restricted filesystem access, dropped capabilities, and only the networking capabilities strictly required. 6. **Authenticate selected configuration material.** Pin a trusted source or verify profiles against administrator-maintained hashes or signatures before activation. 7. **Use safe temporary storage.** Replace the fixed `/tmp/vpn_list.csv` path with a securely created temporary file or process the response in memory, and ensure restrictive permissions for the final profile. 8. **Fail closed.** If profile parsing, validation, provenance checks, or isolation setup fails, do not invoke OpenVPN.
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (153)

Self-Modification

High
Category
Rogue Agent
Content
### Changed
- Package directory renamed from `spot` to `ocas-spot` (OCAS spec compliance)
- Platform table updated: SevenRooms ✅, Resy ✅, Tock ⚠️, OpenTable ⚠️ (session required)
- `self_update.source` updated to `<agent-handle>/ocas-spot`
- `skill.json` `requires` now lists `npm` and `pip` dependencies explicitly
- `filesystem.write` updated: `ocas-elephas` intake path corrected to `{agent_root}/commons/db/ocas-elephas/intake/`
- `filesystem.read` extended to include `ocas-voyage/itineraries/`
Confidence
90% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill claims broad multi-platform booking and monitoring functionality, but the flagged behavior suggests a narrower implementation combined with direct VPN rotation and anti-bot evasion techniques. Misrepresenting both coverage and infrastructure behavior is dangerous because it can conceal risky access methods and lead reviewers to underestimate how much generic scraping or traffic obfuscation the skill performs.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill claims broad multi-platform booking and monitoring functionality, but the flagged behavior suggests a narrower implementation combined with direct VPN rotation and anti-bot evasion techniques. Misrepresenting both coverage and infrastructure behavior is dangerous because it can conceal risky access methods and lead reviewers to underestimate how much generic scraping or traffic obfuscation the skill performs.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill claims broad multi-platform booking and monitoring functionality, but the flagged behavior suggests a narrower implementation combined with direct VPN rotation and anti-bot evasion techniques. Misrepresenting both coverage and infrastructure behavior is dangerous because it can conceal risky access methods and lead reviewers to underestimate how much generic scraping or traffic obfuscation the skill performs.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill claims broad multi-platform booking and monitoring functionality, but the flagged behavior suggests a narrower implementation combined with direct VPN rotation and anti-bot evasion techniques. Misrepresenting both coverage and infrastructure behavior is dangerous because it can conceal risky access methods and lead reviewers to underestimate how much generic scraping or traffic obfuscation the skill performs.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill claims broad multi-platform booking and monitoring functionality, but the flagged behavior suggests a narrower implementation combined with direct VPN rotation and anti-bot evasion techniques. Misrepresenting both coverage and infrastructure behavior is dangerous because it can conceal risky access methods and lead reviewers to underestimate how much generic scraping or traffic obfuscation the skill performs.

Self-Modification

High
Category
Rogue Agent
Content
### Maintenance

`spot.update` — Pull latest release from GitHub. Preserves `{agent_root}/commons/data/ocas-spot/` and journals. See `references/self-update.md` for the update procedure.

## NLP parsing
Confidence
97% confidence
Finding
Runtime self-update is a classic self-modification risk: the skill can fetch and install new code from a remote source after initial review. Because this skill also has filesystem, shell, network, and automation capabilities, a malicious or compromised update could materially change behavior and execute arbitrary actions with the skill's privileges.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The skill says calendar sync/conflict handling is out of scope, yet it performs conflict-check and event-creation requests against another calendar-related skill. This inconsistency is risky because users and reviewers may not realize the skill handles scheduling metadata and can transmit booking details into another subsystem despite disclaiming calendar responsibility.

Self-Modification

High
Category
Rogue Agent
Content
## Background tasks

During `spot.init`, cron registration for spot jobs is handled via `cronjob(action='create', ...)`. No heartbeat registry needed. See `references/self-update.md` for the cron registration pattern.

## OKRs
Confidence
90% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Self-Modification

High
Category
Rogue Agent
Content
## Background tasks

During `spot.init`, cron registration for spot jobs is handled via `cronjob(action='create', ...)`. No heartbeat registry needed. See `references/self-update.md` for the cron registration pattern.

## OKRs
Confidence
90% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Self-Modification

High
Category
Rogue Agent
Content
|| `references/cron-sweep-pattern.md` | Before running watch sweeps via cron — browser lifecycle, error handling, and sequencing for automated sweeps. |
|| `references/watch-sweep-behavior.md` | Before designing or modifying sweep logic — detailed behavioral spec for watch sweep edge cases. |

## Self-update

Run `spot.update` to pull the latest release. See `references/self-update.md` for the full procedure.
Confidence
96% confidence
Finding
This section explicitly documents a command that pulls the latest release, confirming live code modification capability. In context, the danger is amplified by the skill's ability to run background jobs, interact with external services, and write local state, making post-review code drift particularly risky.

Self-Modification

High
Category
Rogue Agent
Content
## Self-update

Run `spot.update` to pull the latest release. See `references/self-update.md` for the full procedure.
Confidence
96% confidence
Finding
This line reiterates the operational self-update instruction, reinforcing that the skill is intended to modify its own codebase from a remote source. Repeated emphasis on runtime update behavior is concerning because it normalizes bypassing normal review controls for a high-privilege automation skill.

Ssd 3

High
Confidence
98% confidence
Finding
The file explicitly tells the agent to ask the user for Booksy account credentials to complete a booking. Direct credential collection by an automation agent is a sensitive-data security issue because it can lead to phishing-like patterns, insecure storage, overbroad access, and compromise of the user's third-party account.

Credential Access

High
Category
Privilege Escalation
Content
### Authentication

Calendly API uses personal access tokens or OAuth. For personal use:

1. Go to https://calendly.com/integrations/api_keys
2. Generate a personal access token
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
Calendly API uses personal access tokens or OAuth. For personal use:

1. Go to https://calendly.com/integrations/api_keys
2. Generate a personal access token
3. Store in environment: `CALENDLY_API_TOKEN=your_token_here`

### API Endpoints
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The runbook instructs operators to kill browser and supervisor processes as part of normal recovery logic, which exceeds the stated booking/checking scope and introduces destructive host-level actions. In an agent environment, embedding process-termination guidance can be repurposed to disrupt unrelated workloads or destabilize the host if process matching is wrong or reused elsewhere.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
This section explicitly directs writing a shell script to /tmp and executing it to kill Chrome and agent-browser processes. That is a real capability escalation from venue booking into arbitrary file-write and shell execution, and it creates a reusable pattern for destructive command execution on the host.

Self-Modification

High
Category
Rogue Agent
Content
# Self-Update Procedure

`spot.update` pulls the latest package from the `source:` URL in this file's frontmatter. Runs silently — no output unless the version changed or an error occurred.
Confidence
97% confidence
Finding
A documented self-update/self-modification mechanism is inherently risky because it allows the skill to alter its own code and prompts after deployment. In this skill's context, self-modification is unnecessary for booking/discovery tasks and creates a high-risk pathway for persistence, stealthy behavior changes, and bypass of normal review controls.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The procedure performs a self-update by pulling a tarball from a repository indicated by frontmatter and then recursively copying its contents over the local skill directory. This gives the skill a remote code/content installation path unrelated to its stated booking and discovery purpose, and there is no integrity verification, allowlist, or human approval before overwrite.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The documented commands download a remote tarball from GitHub and install it directly via extraction and `cp -R`, effectively granting arbitrary repository content installation. Because the skill is for appointments and venue discovery, this capability is unjustified by context and materially increases the risk of supply-chain compromise or intentional repo takeover leading to malicious code or prompt content deployment.

Credential Access

High
Category
Privilege Escalation
Content
'--mute-audio',
    '--no-pings',
    '--password-store=basic',
    '--use-mock-keychain',
]

# Stealth init scripts
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Privileged Container / Container Escape

High
Category
Privilege Escalation
Content
### Docker can't reach host.docker.internal
- On Linux, add `extra_hosts: ["host.docker.internal:host-gateway"]` to docker-compose.yml (already in patched version)
- Alternative: use `--network host` mode (less isolated)
Confidence
88% confidence
Finding
Recommending `--network host` weakens container isolation by placing the container on the host network stack, increasing exposure of local services and making lateral access easier if the containerized browser or agent is compromised. In a stack that already exposes CDP, VNC, and proxy-related components, reducing network isolation substantially raises the blast radius of a compromise.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
log() { echo "[entrypoint] $*"; }

# ── 0. Clean up stale X lock (left by a previous container restart) ───────────
rm -f "/tmp/.X${DISPLAY_NUM}-lock" "/tmp/.X11-unix/X${DISPLAY_NUM}" 2>/dev/null || true

# ── 1. Xvfb ──────────────────────────────────────────────────────────────────
log "Starting Xvfb on display ${DISPLAY}..."
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

High
Confidence
99% confidence
Finding
The script starts x11vnc with the -nopw flag, which exposes the full browser session without authentication to anyone who can reach the VNC port or the noVNC websocket bridge. Because this environment persists Chrome profile data and is used for booking and account-backed workflows, an attacker could observe or control active sessions, steal cookies, and perform actions as the user.

External Script Fetching

High
Category
Supply Chain
Content
}

status_chrome() {
    if curl -sf "http://${CDP_BIND}:${CDP_PORT}/json/version" >/dev/null 2>&1; then
        local VER
        VER=$(curl -sf "http://${CDP_BIND}:${CDP_PORT}/json/version" | python3 -c "import sys,json; print(json.load(sys.stdin).get('Browser','unknown'))" 2>/dev/null)
        log "Chrome is UP — ${VER} — CDP at ${CDP_BIND}:${CDP_PORT}"
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Static analysis

Detected: suspicious.install_untrusted_source

Install source points to URL shortener or raw IP.

Warn
Code
suspicious.install_untrusted_source
Location
references/virtualperson-patches/docker-compose.yml:28