Back to skill

Security audit

Check and book Tennis and Pickleball Courts at Bay Club Gateway

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be a real Bay Club court-booking bot, but it can automatically make bookings, accept page checkboxes, choose partners, and write calendar events with too little user confirmation or scoping.

Review this skill carefully before installing. It should only be used if you are comfortable giving it Bay Club credentials and allowing it to make real reservations. Avoid using the booking action until it adds an explicit final confirmation step, stops auto-selecting partners, stops blanket-clicking checkboxes, and narrows Google Calendar credential handling and OAuth scope.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
BayClubBot.ts:458
Finding

Booking Flow Silently Selects a Hardcoded or Arbitrary Third-Party Partner

Content
View full analysis
{ // Find all elements that might contain buddy/person info const allElements = Array.from(document.querySelectorAll('*')); // Look for Samuel Wang or Emma Campbell const samuelOrEmma = allElements.filter(el => { const text = el.textContent || ''; return text.includes('Samuel Wang') || text.includes('Emma Campbell'); }); // Click the most specific (smallest) element if (samuelOrEmma.length > 0) { // Sort by text length to get most specific samuelOrEmma.sort((a, b) => (a.textContent?.length || 999) - (b.textContent?.length || 999) ); const buddy = samuelOrEmma[0] as HTMLElement; buddy.scrollIntoView({ block: 'center' }); buddy.click(); console.log('Selected buddy:', buddy.textContent?.trim().substring(0, 50)); return true; } // Fallback: click any app-racquet-sports-person element const personElements = Array.from(document.querySelectorAll('app-racquet-sports-person')); if (personElements.length > 0) { (personElements[0] as HTMLElement).click(); console.log('Selected first person element'); return true; } console.log('No buddy elements found'); return false; }); ``` ### Technical Analysis The public booking operation accepts only `sport`, `day`, and `time`. It does not accept a partner identity or record user approval to associate another person with the reservation. Despite this, the browser autom ...[truncated 1772 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
BayClubBot.ts:501
Finding

Booking Flow Automatically Accepts Every Checkbox Before Confirmation

Content
View full analysis
{ const checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]')); checkboxes.forEach(cb => { if (!(cb as HTMLInputElement).checked) { (cb as HTMLInputElement).click(); console.log('Checked a checkbox'); } }); }); ``` ### Technical Analysis The code selects every unchecked checkbox present on the booking page. It does not: - Determine whether a checkbox is required. - Inspect or present its associated label. - Distinguish legal terms and waivers from optional marketing consent. - Restrict selection to known controls. - Obtain explicit user approval. The comment acknowledges that these controls may represent terms or policies, but the implementation accepts them indiscriminately. Any new checkbox introduced by the website would also be selected automatically, creating an unsafe fail-open behavior. ### Attack Path 1. A user asks the Skill to book a court. 2. The automation reaches the final booking page. 3. The page contains one or more unchecked controls, such as a waiver, policy acknowledgment, optional communication preference, or another consent. 4. The script queries all checkbox inputs. 5. It clicks every unchecked checkbox without identifying its purpose. 6. The script then clicks the final “CONFIRM BOOKING” control. 7. The booking is submitted with all displayed acknowledgments or options enabled. A malicious or compromised target page could exploit this behavior by adding a consequential checkbox to the booking form, which the automation would select automatically. ### Impact Assessment The user may unknowingly: - Accept legal terms, waiv ...[truncated 382 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
GoogleCalendarService.js:37
Finding

Google Calendar Integration Requests Broader OAuth Access Than Required

Content
View full analysis
Remediation
View remediation
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 (41)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code iterates over every unchecked checkbox and clicks it blindly before confirmation. On a booking site, checkboxes may represent terms of service, waivers, billing consent, marketing consent, or policy acknowledgements, so mass-selecting them can cause the user to accept legal or operational obligations they never reviewed.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Automatically checking undisclosed checkboxes immediately before booking is a silent consent bypass. Even if technically needed to complete the flow, it suppresses meaningful user review of contractual or policy text and compounds the risk of the subsequent automatic confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The bot proceeds to click the final 'CONFIRM BOOKING' action automatically, with no user-facing review or approval immediately before the irreversible reservation step. In this skill context, that can create real bookings, consume scarce court inventory, trigger penalties or fees, and commit the user to selections they may not have intended.

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 · GoogleCalendarService.js (reported line 19)May include surrounding context.

js
try {
      // Check for credentials file or environment variable
      const credentialsPath = process.env.GOOGLE_CALENDAR_CREDENTIALS_PATH 
        || resolve(__dirname, 'google-calendar-credentials.json');
      
      const credentialsJson = process.env.GOOGLE_CALENDAR_CREDENTIALS;

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The instructions tell users to copy a Google service-account JSON key into the bot workspace, which is a sensitive credential containing private key material. In an agent framework that can read local files, storing long-lived credentials in an easily accessible project directory materially increases the risk of credential theft, unauthorized calendar access, and lateral use of the service account.

Content

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

Copy the JSON to the bot directory:

bash
cp ~/Downloads/your-key.json ~/.openclaw/workspace/skills/bayclub_manager/google-calendar-credentials.json

Set your calendar ID:

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

ke one called "Court Bookings")

  • Settings → Share with specific people
  • Add the service account email (it's in the JSON: client_email)
  • Give it "Make changes to events" permission

3. Add credentials

Copy the JSON to the bot directory:

bash
cp ~/Downloads/your-key.json ~/.openclaw/workspace/skills/bayclub_manager/google-calendar-credentials.json

Set your calendar ID:

bash
echo 'export GOOGLE_CALENDAR_ID="your-email@gmail.com"' >> ~/.bashrc
source ~/.bashrc

That's it. Future bookings will show up in your calendar automatically.

Usage

Via WhatsApp (Natural Language)

Just text your OpenClaw agent:

  • "Check tennis courts for Sunday"
  • "Book pickleball Saturday at 10am"
  • "What's available tomorrow?"

Via Command Line

bash
# Check what's open
NODE_ENV=development STAGEHAND_ENV=LOCAL HEADLESS=true npx ts-node cli.ts check tennis saturday

# Book a slot
NODE_ENV=development STAGEHAND_ENV=LOCAL HEADLESS=true npx ts-node cli.ts book pickleball su

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description omits access to Google Calendar via service-account credentials and creation of external calendar events. Hidden use of external credentials and third-party resource modification expands the trust boundary significantly and can lead to unauthorized data access or side effects outside the Bay Club booking context.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description omits access to Google Calendar via service-account credentials and creation of external calendar events. Hidden use of external credentials and third-party resource modification expands the trust boundary significantly and can lead to unauthorized data access or side effects outside the Bay Club booking context.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
96% confidence
Finding

form-data 4.0.5 is flagged for CRLF injection in multipart field names/filenames, which can enable request smuggling or manipulation of downstream multipart parsing when attacker-controlled field metadata is embedded into outbound requests. This is more concerning in an automation/integration skill because it may interact with external web services and APIs, increasing the chance that untrusted input could be relayed into multipart requests.

Content

No source excerpt is available for this finding.

Possible Typosquatting: 'gaxios' resembles popular package 'axios'

High
Category
Supply Chain
Confidence
70% confidence
Finding

Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: jsondiffpatch==0.6.0 — 2 advisory(ies): CVE-2025-9910 (jsondiffpatch is vulnerable to Cross-site Scripting (XSS) via HtmlFormatter::nod); CVE-2026-8657 ( jsondiffpatch patch APIs are vulnerable to prototype pollution)

High
Category
Supply Chain
Confidence
87% confidence
Finding

jsondiffpatch 0.6.0 is reported vulnerable to XSS in HTML formatting and prototype pollution in patch APIs. Because this file only shows the dependency and not actual use of HtmlFormatter or patch application on untrusted objects, exploitability is contextual; however, inclusion of a package with two high-severity classes of bugs is still a valid vulnerability finding. In this backend-oriented booking skill, XSS risk is likely lower, but prototype pollution could still matter if untrusted diffs are processed anywhere in the stack.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: nanoid==3.3.11 — 3 advisory(ies): CVE-2026-67214 (nanoid: non-secure generators can loop indefinitely with negative size); CVE-2026-67213 (nanoid: custom generators can loop indefinitely when size is zero); CVE-2026-73086 (nanoid: Integer Overflow or Wraparound)

High
Category
Supply Chain
Confidence
84% confidence
Finding

nanoid 3.3.11 is flagged for edge-case denial-of-service and integer handling issues in non-secure/custom generator paths. This is a real vulnerability in the package version, though practical exposure depends on whether the skill or its dependencies use the affected APIs with attacker-controlled sizes or custom generators; many consumers only use the safe default path.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
95% confidence
Finding

ws 8.19.0 is flagged for memory disclosure and memory-exhaustion denial of service. This is particularly relevant in a browser automation skill because WebSocket transport is commonly used by Playwright, browser-control tooling, and AI streaming integrations, so an exposed or attacker-reachable WS channel could have meaningful confidentiality and availability impact.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The bot auto-selects specific named playing partners ('Samuel Wang' or 'Emma Campbell') without deriving that choice from explicit user input. This exceeds the stated purpose of court booking by making a consequential selection on behalf of the user, and it can create unauthorized reservations, privacy issues, or social/accountability problems for the named people.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Event creation always uses the 'America/Los_Angeles' time zone, regardless of the user's actual locale or preference. This is a natural-language policy concern because it imposes a fixed locale setting without opt-in or an explicit documented regional constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code sends booking details, including summary, location, description, and buddy name, to Google Calendar without any consent, notice, or confirmation mechanism in this component. In a booking skill, that creates a real privacy risk because personal scheduling data is transmitted to a third party and persisted externally, potentially without the user's explicit awareness at the point of action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README advertises booking courts and modifying Google Calendar via WhatsApp/text, but it does not clearly warn users that natural-language messages can trigger actions against external accounts. In an agentic environment, this increases the risk of unintended bookings, account changes, or social-engineering-driven misuse because users may not realize that messages cause real-world side effects.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · README.md (reported line 25)May include surrounding context.

md
### Option 1: DigitalOcean (Easiest)

1. Go to the [OpenClaw marketplace page](https://marketplace.digitalocean.com/apps/openclaw)
2. Click "Create OpenClaw Droplet"
3. Pick the $21/month plan
4. Wait ~2 minutes for it to boot

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README instructs users to store Bay Club credentials and Google service-account material without discussing secret handling, file permissions, or the sensitivity of calendar access. This can lead to accidental credential exposure, especially in shared home directories, repos, backups, or agent-accessible workspaces where secrets may be read or exfiltrated.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
60% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

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

bash
# Check what's open
NODE_ENV=development STAGEHAND_ENV=LOCAL HEADLESS=true npx ts-node cli.ts check tennis saturday

# Book a slot
NODE_ENV=development STAGEHAND_ENV=LOCAL HEADLESS=true npx ts-node cli.ts book pickleball sunday "10:00 AM - 11:00 AM"

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
60% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

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

bash
# Check what's open
NODE_ENV=development STAGEHAND_ENV=LOCAL HEADLESS=true npx ts-node cli.ts check tennis saturday

# Book a slot
NODE_ENV=development STAGEHAND_ENV=LOCAL HEADLESS=true npx ts-node cli.ts book pickleball sunday "10:00 AM - 11:00 AM"

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes a shell command and relies on environment variables, but the manifest does not declare an explicit tool scope or allowed-tools boundary. That omission weakens least-privilege controls and makes it easier for the skill to gain broader execution capability than users or reviewers would expect.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

Using npx ts-node without a pinned version allows resolution of whatever package version is available at runtime, which can change unexpectedly or be influenced by supply-chain compromise. Because this command is executed through the shell, an attacker controlling dependencies or package resolution could achieve arbitrary code execution in the agent environment.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.