Back to skill

Security audit

Calendar Reminder 日历提醒

Security checks for vulnerabilities and agentic risk

Overview

This calendar reminder skill does what it says, but it can repeatedly send private calendar details to a bundled Feishu recipient unless the user edits the code correctly.

Review before installing. Only use this if you are comfortable with recurring Outlook calendar scanning and Feishu delivery, replace the Feishu target before any run, verify the scheduled cron entry, and consider removing or rewriting the code so it refuses to send messages until an explicit recipient is configured.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
calendar_reminder.py:118
Finding

Hard-Coded Feishu Recipient Can Cause Unauthorized Calendar Data Disclosure

Content
View full analysis

Vulnerability Details

File Location: calendar_reminder.py:118-125
Vulnerability Type: Hard-coded external data recipient
Risk Level: High

Vulnerable Code

python
def send_feishu(text: str):
    subprocess.run([
        "openclaw", "message", "send",
        "--channel", "feishu",
        "--target", "user:ou_159cbb6a3791ff5a98f3a2a4b38e7d4c",
        "-m", text,
    ], timeout=15)

Technical Analysis

The script embeds a specific Feishu user identifier directly in executable code. Every scan summary and calendar-fetching error passed to send_feishu() is therefore sent to that account unless the user manually modifies the source.

Although SKILL.md instructs users to replace this identifier, the default executable behavior remains unsafe. The information sent can include:

  • Calendar dates and event times
  • Event subjects
  • All-day event subjects
  • Scan status and diagnostic errors
  • Error text emitted by the Outlook calendar dependency

The hard-coded identifier is not necessarily a credential, but it defines an external recipient for potentially confidential information. No runtime confirmation or configuration validation prevents execution with the bundled recipient.

Attack Path

  1. A user installs the skill without manually reviewing or changing the embedded Feishu identifier.
  2. The user or nightly scheduled job runs calendar_reminder.py.
  3. The script retrieves Outlook calendar events.
  4. Event subjects, times, dates, and scan results are incorporated into a summary.
  5. send_feishu() sends the summary to the hard-coded Feishu account.
  6. The account holder receives private calendar metadata without authorization from the affected user.

If calendar retrieval fails, dependency-generated error details can be sent through the same path.

Impact Assessment

Successful exploitation does not directly grant local system privileges or code execution. Ho ...[truncated 423 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the bundled recipient identifier from the source code.
  2. Require the recipient to be supplied explicitly through a protected configuration file, environment variable, or OpenClaw configuration mechanism.
  3. Refuse to start when the recipient is absent, malformed, or still set to a documented placeholder.
  4. Require an explicit setup or confirmation step before the first message is sent.
  5. Avoid sending raw exception or dependency error output to external messaging services. Log detailed errors locally and send only a generic failure message.
  6. Document the exact categories of calendar information transmitted and obtain user consent before enabling scheduled delivery.
  7. Consider allowlisting expected recipient identifiers and channels in configuration.
  8. Add tests verifying that the application cannot send messages when no user-configured recipient is present.

A safer configuration pattern would be:

python
import os

FEISHU_TARGET = os.environ.get("CALENDAR_REMINDER_FEISHU_TARGET")
if not FEISHU_TARGET:
    raise RuntimeError(
        "CALENDAR_REMINDER_FEISHU_TARGET must be configured explicitly"
    )

The configured value should then replace the hard-coded --target argument.

T01 · Skill Instruction Hijacking

Error
Location
calendar_reminder.py:39
Finding

Untrusted Calendar Subjects Are Embedded in Agent Cron Messages

Content
View full analysis

Vulnerability Details

File Location: calendar_reminder.py:39-50, 78-94
Vulnerability Type: Indirect prompt injection through scheduled Agent messages
Risk Level: High

Vulnerable Code

The cron registration function passes the generated text to OpenClaw as a message:

python
def add_once_cron(at_sh: datetime, message: str):
    """at_sh 是上海时间的 datetime(带 tzinfo=TZ),转成 UTC ISO 传给 --at"""
    global _cron_counter
    _cron_counter += 1
    utc = ZoneInfo("UTC")
    at_utc = at_sh.astimezone(utc)
    at_iso = at_utc.strftime("%Y-%m-%dT%H:%M:%SZ")
    name = f"cal-remind-{at_sh.strftime('%Y-%m-%d')}-{_cron_counter}"
    subprocess.run([
        "openclaw", "cron", "add",
        "--name", name,
        "--at", at_iso,
        "--delete-after-run",
        "--message", message,
        "--announce",
        "--channel", "feishu",
    ], check=True, timeout=15)

Calendar-controlled event subjects are inserted into those messages without a trust-boundary marker or prompt-injection defense:

python
# 上午日程:提前2小时
for ev in morning:
    remind_dt = ev["_start_dt"] - timedelta(hours=2)
    if remind_dt <= now:
        remind_dt = now + timedelta(minutes=2)
    msg = f"📅 提醒(2小时后):{ev['_start_sh']} {ev['subject']}"
    add_once_cron(remind_dt, msg)
    reminders.append(f"  • {ev['_start_sh']} {ev['subject']} → {remind_dt.strftime('%H:%M')} 提醒")

# 下午日程:统一 12:00 提醒
if afternoon:
    remind_dt = datetime(tomorrow.year, tomorrow.month, tomorrow.day, 12, 0, tzinfo=TZ)
    if remind_dt <= now:
        remind_dt = now + timedelta(minutes=2)
    lines = "\n".join([f"  • {ev['_start_sh']} {ev['subject']}" for ev in afternoon])
    msg = f"📅 下午日程提醒:\n{lines}"
    add_once_cron(remind_dt, msg)
    for ev in afternoon:
        reminders.append(f"  • {ev['_start_sh']} {ev['subject']} → 12:00 提醒")

Technical Analysis

Calendar subjects are externally ...[truncated 2281 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not deliver calendar-controlled text through an instruction-bearing agent message channel.
  2. Prefer a notification-only API that sends directly to Feishu without invoking an AI agent.
  3. If agent processing is unavoidable, place event data in a structured data field and enforce a trusted instruction stating that calendar content is untrusted data and must never be executed.
  4. Encode or escape any markup and structured-message syntax recognized by the downstream system.
  5. Reject control characters and impose conservative subject-length limits.
  6. Where feasible, permit only expected display characters in event subjects.
  7. Configure the scheduled session with the minimum possible tools and permissions.
  8. Require approval before any tool operation derived from calendar content.
  9. Add adversarial tests using event subjects containing instruction-like text, role markers, multiline payloads, and tool-call requests.
  10. Confirm from OpenClaw documentation that the selected cron option produces an inert announcement rather than an agent instruction. If that guarantee is unavailable, treat the channel as instruction-bearing.

A safer architecture is to create a fixed scheduled task containing only an opaque event identifier. At execution time, trusted code should retrieve and format the event and send it directly through a non-agent notification interface.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description understates important behavior: the skill can register a persistent cron job, automatically scan calendar data on a schedule, and send outbound Feishu messages to a configured recipient. This mismatch reduces informed consent and can cause users to approve a skill without realizing it establishes ongoing automation and external data transmission.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes shell-capable behavior via installation and execution commands but does not declare any tool scope or allowed-tools boundary. That weakens least-privilege controls and makes it harder for users or policy systems to understand that the skill can register cron jobs and run local commands affecting the host environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The natural-language description is entirely in Chinese, and the configured system event text is also fixed in Chinese, indicating a language constraint without user opt-in. The file does not state that the skill is region-specific or provide an alternative language option, which is a language/locale policy issue under the stated rules.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documentation describes functionality but omits a clear warning that it continuously processes Outlook calendar content and sends notifications through Feishu on a recurring schedule. Because calendar entries may contain sensitive business or personal information, users may unknowingly enable periodic exfiltration of meeting metadata to another platform.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The system-event payload contains a fixed Chinese instruction string, which enforces a specific language in operational behavior. There is no accompanying note that the skill is limited to Chinese-speaking users or any configurable locale support.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language description and implementation assume a fixed China locale context: the docstring is entirely in Chinese and the code hard-codes Asia/Shanghai for scheduling behavior. There is no user opt-in, locale selection, or documented justification that this skill is intentionally limited to a China-specific environment.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · calendar_reminder.py (reported line 21)May include surrounding context.

python
# ── 拉取明天日程 ──────────────────────────────────────────────
def fetch_tomorrow_events():
    result = subprocess.run(
        ["python3", str(SKILL_DIR / "owa_calendar.py"), "--tomorrow", "--json"],
        capture_output=True, text=True, timeout=60
    )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · calendar_reminder.py (reported line 41)May include surrounding context.

python
at_utc = at_sh.astimezone(utc)
    at_iso = at_utc.strftime("%Y-%m-%dT%H:%M:%SZ")
    name = f"cal-remind-{at_sh.strftime('%Y-%m-%d')}-{_cron_counter}"
    subprocess.run([
        "openclaw", "cron", "add",
        "--name", name,
        "--at", at_iso,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill sends calendar-derived content, including event subjects and schedule details, to Feishu automatically and to a hard-coded user target, without any consent flow, minimization, or disclosure mechanism. Calendar entries often contain sensitive business or personal information, so this creates a real confidentiality risk if the recipient is incorrect, shared, or not expected by the user.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · calendar_reminder.py (reported line 124)May include surrounding context.

python
def send_feishu(text: str):
    subprocess.run([
        "openclaw", "message", "send",
        "--channel", "feishu",
        "--target", "user:ou_159cbb6a3791ff5a98f3a2a4b38e7d4c",

Static analysis

No suspicious patterns detected.