Back to skill

Security audit

appointment-scheduler

Security checks for vulnerabilities and agentic risk

Overview

This appointment scheduler is mostly purpose-aligned, but it handles customer data and Google Calendar access with overbroad permissions, weak local data protections, and insufficient user controls.

Install only after reviewing the data-handling model. Use a dedicated calendar, restrict token and data-file permissions, avoid syncing phone numbers or notes unless customers have consented, validate date inputs before use, and treat cron-based reminders or sync as an explicit opt-in because they keep running after setup.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/book.js:18
Finding

Path Traversal Through Unvalidated Date Arguments

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/sync-google-calendar.js:51
Finding

Overprivileged Google Calendar Authorization and Unnecessary PII Synchronization

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/book.js:79
Finding

Plaintext Customer Records Created Without Explicitly Restrictive Permissions or Retention Controls

Content
View full analysis
a.time.localeCompare(b.time)); // Save fs.writeFileSync(dailyFile, JSON.stringify(bookings, null, 2)); ``` From `scripts/waitlist.js`: ```js const entry = { id: crypto.randomBytes(6).toString('hex'), date, time, customer: { name: customer, phone: phone || null, email: email || null }, added_at: new Date().toISOString(), notified: false }; waitlist.push(entry); fs.writeFileSync(filePath, JSON.stringify(waitlist, null, 2)); ``` From `scripts/mark-noshow.js`: ```js history.push({ booking_id: booking.id, customer_name: booking.customer.name, customer_phone: booking.customer.phone, customer_email: booking.customer.email, date: booking.date, time: booking.time, service: booking.service, marked_at: booking.noshow_marked_at }); fs.writeFileSync(HISTORY_FILE, JSON.stringify(history, null, 2)); ``` ```js flagged[key] = { customer_name: booking.customer.name, phone: booking.customer.phone, email: booking.customer.email, noshow_count: customerNoshows.length, flagged_at: new Date().toISOString(), require_deposit: config.noshow_policy?.require_deposit_when_flagged || false }; fs.writeFileSync(FLAGGED_FILE, JSON.stringify(flagged, null, 2)); ``` From `scripts/send-reminders.js`: ```j ...[truncated 2730 chars]
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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This mismatch becomes security-relevant because the skill claims broad appointment automation while also referencing access to OAuth credentials, tokens, and local data without declaring permissions. Users may consent based on the stated purpose without realizing the actual behavior includes sensitive credential and file access, creating a transparency and over-privilege risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding

This mismatch becomes security-relevant because the skill claims broad appointment automation while also referencing access to OAuth credentials, tokens, and local data without declaring permissions. Users may consent based on the stated purpose without realizing the actual behavior includes sensitive credential and file access, creating a transparency and over-privilege risk.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The skill explicitly references storage and use of Google Calendar OAuth credential and token files in the user's home directory. In this context, those secrets enable ongoing access to external calendar data and operations, so insufficient protection or unexpected access to them can lead to unauthorized reading, modification, or persistence in the connected account.

Content

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

md
### Google Calendar

1. Enable Google Calendar API
2. Download OAuth credentials → save as `~/.secrets/google-calendar-credentials.json`
3. First run will prompt browser auth
4. Refresh token saved to `~/.secrets/google-calendar-token.json`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| 예약 파싱 실패 | Check `parse-booking.js` output, add custom patterns |

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.

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 · README.md (reported line 137)May include surrounding context.

md
* 
 * Setup:
 * 1. Enable Google Calendar API in Google Cloud Console
 * 2. Download OAuth credentials → save as ~/.secrets/google-calendar-credentials.json
 * 3. First run will open browser for auth
 * 4. Refresh token saved to ~/.secrets/google-calendar-token.json
 */

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 · scripts/sync-google-calendar.js (reported line 8)May include surrounding context.

js
* 
 * Setup:
 * 1. Enable Google Calendar API in Google Cloud Console
 * 2. Download OAuth credentials → save as ~/.secrets/google-calendar-credentials.json
 * 3. First run will open browser for auth
 * 4. Refresh token saved to ~/.secrets/google-calendar-token.json
 */

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 · scripts/sync-google-calendar.js (reported line 17)May include surrounding context.

js
* 
 * Setup:
 * 1. Enable Google Calendar API in Google Cloud Console
 * 2. Download OAuth credentials → save as ~/.secrets/google-calendar-credentials.json
 * 3. First run will open browser for auth
 * 4. Refresh token saved to ~/.secrets/google-calendar-token.json
 */

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 · scripts/sync-google-calendar.js (reported line 30)May include surrounding context.

js
* 
 * Setup:
 * 1. Enable Google Calendar API in Google Cloud Console
 * 2. Download OAuth credentials → save as ~/.secrets/google-calendar-credentials.json
 * 3. First run will open browser for auth
 * 4. Refresh token saved to ~/.secrets/google-calendar-token.json
 */

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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 80)May include surrounding context.

Cron Setup (자동화)

bash
# crontab -e 실행 후 추가:

# 매일 오전 9시: 하루 전 리마인더
0 9 * * * cd /Users/mupeng/.openclaw/workspace/skills/appointment-scheduler/scripts && node send-reminders.js --type day-before

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README explicitly describes automated reminder and waitlist notifications and Google Calendar sync for bookings containing customer names and phone numbers, but it provides no privacy notice, consent requirement, data-minimization guidance, or warning that personal data will be transmitted to external systems. In an appointment-booking skill handling customer PII, this omission increases the risk of unauthorized disclosure or non-compliant data handling through messaging and calendar integrations.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill describes use of environment-dependent capabilities, local files, OAuth secrets, cron, and external calendar/message integrations, but it declares no explicit tool scope or permissions. That omission weakens reviewability and least-privilege controls, making it easier for a host agent to grant broader access than users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill processes customer names, phone numbers, booking details, reminders, and no-show history, all of which are personal data, yet it provides no privacy notice, consent flow, retention policy, or handling guidance. In an appointment-management context, this increases the risk of unlawful collection, oversharing, and insecure storage of customer information.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Much of the operational content, examples, service names, reminder text, and troubleshooting material are written in Korean, which can impose a language constraint on users. The file does not explicitly offer alternative language support or state that the skill is intentionally Korean-only for a defined regional context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file instructs users to store OAuth credentials and refresh tokens locally and to sync appointment data to third-party calendars, but it gives no warning about the sensitivity of those secrets or the exposure of customer data to external services. Compromise of these files could allow persistent calendar access and disclosure or manipulation of appointment records.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The test results explicitly demonstrate storage of personally identifiable information such as customer names, phone numbers, booking history, and no-show status in local workspace files, but do not mention retention, access controls, or user-facing disclosure. In an appointment-management context, this creates a real privacy risk because operators may persist sensitive customer data without understanding where it is stored or how long it remains available.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The file states Google Calendar sync is a feature and recommends documenting OAuth setup, but it does not warn that enabling sync may transmit appointment details and customer metadata to an external third-party service. In this skill, appointment data likely includes sensitive scheduling and contact information, so omission of this disclosure can lead to unintended external sharing.

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 · TESTING.md (reported line 130)May include surrounding context.

md
- **Next step**: Document OAuth setup process for users

3. **Reminder Timing**: Requires cron setup or manual testing with mock dates
   - **Next step**: Create test mode for reminders

## Recommendations

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script directly prints personally identifiable and potentially sensitive appointment data, including customer names, phone numbers, and free-form notes, to stdout. In the context of salon/clinic/studio scheduling, this increases the risk of shoulder-surfing, terminal log exposure, shell history capture in surrounding tooling, and accidental disclosure of medical or personal details contained in notes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The default configuration embeds Korean business and service names such as "MUFI 포토부스", "포토촬영", and other Korean-only labels. This imposes a specific language/locale in the generated config without user opt-in or any indication that the skill is region-specific, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This script makes immediate, persistent changes to booking status, no-show history, and customer flagging records with no confirmation prompt, dry-run mode, undo capability, or secondary validation of operator intent. In an appointment-management context, a mistaken or automated invocation can wrongly label customers as no-shows and trigger downstream penalties such as deposit requirements, creating operational and reputational harm.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The usage example is exclusively in Korean and the extraction logic is explicitly tied to Korean keywords and Korean-name patterns, which makes the skill effectively operate only for Korean-language booking requests. There is no user opt-in, language choice, or documented justification that this is a Korea-specific or Korean-only skill, so this is a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The message templates use Korean text directly and the code does not offer any language selection, fallback, or indication that the skill is intentionally limited to Korean-speaking users. This can violate language/locale policy when users or recipients may expect communication in their preferred language.

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 · scripts/sync-google-calendar.js (reported line 29)May include surrounding context.

js
console.error('\nSetup guide:');
  console.error('1. Go to https://console.cloud.google.com/');
  console.error('2. Enable Google Calendar API');
  console.error('3. Create OAuth 2.0 credentials');
  console.error('4. Download and save to ~/.secrets/google-calendar-credentials.json');
  process.exit(1);
}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script automatically uploads customer PII, including names and phone numbers, into Google Calendar event summaries and descriptions without any explicit consent gate, minimization, or warning at sync time. In an appointment-scheduling context this is sensitive business and customer data, and placing it into a third-party calendar can expose it to broader account access, sharing settings, mobile notifications, and retention outside the local booking system.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/cancel-booking.js:58