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

Content
View full analysis

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
View 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
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.

Content

Scanner excerpt · CHANGELOG.md (reported line 108)May include surrounding context.

md
### 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/`

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
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.

Content

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

md
### 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

Context-Inappropriate Capability

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
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.

Content

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

md
## 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

Self-Modification

High
Category
Rogue Agent
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.

Content

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

md
## 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

Self-Modification

High
Category
Rogue Agent
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.

Content

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

md
|| `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.

Self-Modification

High
Category
Rogue Agent
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.

Content

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

md
## Self-update

Run `spot.update` to pull the latest release. See `references/self-update.md` for the full procedure.

Ssd 3

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/platforms/calendly.md (reported line 20)May include surrounding context.

md
### 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

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/platforms/calendly.md (reported line 23)May include surrounding context.

md
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

Context-Inappropriate Capability

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
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.

Content

Scanner excerpt · references/self-update.md (reported line 1)May include surrounding context.

md
# 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.

Description-Behavior Mismatch

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/stealth-config.md (reported line 70)May include surrounding context.

md
'--mute-audio',
    '--no-pings',
    '--password-store=basic',
    '--use-mock-keychain',
]

# Stealth init scripts

Privileged Container / Container Escape

High
Category
Privilege Escalation
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.

Content

Scanner excerpt · references/virtualperson-patches/DEPLOY.md (reported line 173)May include surrounding context.

md
### 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)

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · references/virtualperson-patches/entrypoint.sh (reported line 27)May include surrounding context.

sh
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}..."

Missing User Warnings

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · references/virtualperson-patches/launch-chrome.sh (reported line 41)May include surrounding context.

sh
}

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}"