Back to skill

Security audit

Calendar reminder

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it should be reviewed because it can send your reminder API token and reminder details to any configured URL without enforcing HTTPS or a trusted service origin.

Review the configured REMINDER_API_BASE_URL before installing or using this skill. Use only a trusted HTTPS reminder worker, reserve HTTP for loopback development such as 127.0.0.1, and confirm the exact reminder before delete or feed-token rotation actions because they change remote reminder state or calendar feed access.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/reminder-client.mjs:16
Finding
Bearer Token and Reminder Data May Be Sent Over an Untrusted Plaintext Connection## Vulnerability Details **File Location**: `scripts/reminder-client.mjs:16-25, 92-102` **Vulnerability Type**: Insufficient API endpoint and transport validation **Risk Level**: High ### Vulnerable Code ```js const baseUrl = process.env.REMINDER_API_BASE_URL?.trim(); const token = process.env.REMINDER_API_TOKEN?.trim(); if (!baseUrl) { fail("Missing REMINDER_API_BASE_URL."); } if (!token) { fail("Missing REMINDER_API_TOKEN."); } ``` ```js async function requestJson(pathname, init) { const url = new URL(pathname, ensureTrailingSlash(baseUrl)); const response = await fetch(url, { ...init, headers: { authorization: `Bearer ${token}`, accept: "application/json", ...init?.headers, }, }); const bodyText = await response.text(); if (!response.ok) { const message = bodyText ? `Request failed with ${response.status}: ${bodyText}` : `Request failed with ${response.status}.`; fail(message); } printBody(bodyText); } ``` ### Technical Analysis The client verifies only that `REMINDER_API_BASE_URL` is present. It does not enforce HTTPS, restrict plaintext HTTP to loopback development endpoints, reject embedded URL credentials, or establish that the destination belongs to the intended reminder service. Every request adds `REMINDER_API_TOKEN` as a bearer credential. Create operations also transmit the complete caller-supplied JSON body, which may contain private fields such as `title`, `notes`, `location`, `url`, `start_at`, and raw `source_text`. Network transmission is necessary for the Skill's declared remote reminder functionality. The vulnerability is therefore not the transmission itself, but the absence of minimum transport and destination controls around sensitive transmissions. The configuration guidance permits HTTP for local development, but the implementation does not constrain HTTP to loopback destinations. ...[truncated 1258 chars]
Remediation
## Remediation Suggestions 1. Parse and validate `REMINDER_API_BASE_URL` before processing any command. 2. Require the `https:` scheme for every non-loopback destination. 3. Allow `http:` only for explicitly recognized loopback hosts such as `localhost`, `127.0.0.1`, and `[::1]`. 4. Reject unsupported schemes, malformed ports, fragments, query strings, and URLs containing embedded usernames or passwords. 5. Consider a trusted-origin allowlist or require explicit confirmation when the configured API origin changes. 6. Prevent credential leakage through redirects by disabling automatic redirects or manually validating every redirect destination before resending the authorization header. 7. Document that the bearer token must only be sent to a trusted reminder worker over authenticated TLS. 8. Minimize transmitted personal data by omitting optional fields such as `source_text`, `notes`, or `location` unless required by the user. 9. Add automated tests confirming rejection of remote HTTP endpoints, non-HTTP schemes, embedded credentials, and redirects to untrusted origins.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Ae1

High
Category
analysis-evasion
Content
Reminder operations through `scripts/reminder-client.mjs`.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Reminder operations through `scripts/reminder-client.mjs`.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Delete reminder

```http
DELETE /v1/reminders/:id
Authorization: Bearer <REMINDER_API_TOKEN>
```
Confidence
80% 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).

Session Persistence

Medium
Category
Rogue Agent
Content
---

# ICS Reminder
Use this skill when the user intent is to create or manage a reminder-like event that should appear in a subscribed calendar feed.


Reminder operations through `scripts/reminder-client.mjs`.
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.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The delete path performs an irreversible reminder deletion immediately from a single CLI argument, with no confirmation prompt, dry-run mode, or extra validation. In an agent or automation context, a mistaken tool invocation, malformed identifier mapping, or prompt-injection-driven action could delete user data without an opportunity for the user to catch the error.

Natural-Language Policy Violations

Low
Confidence
72% confidence
Finding
The example uses the timezone "Asia/Shanghai" and Chinese source text "明天下午三点提醒我交水电费" as if they are the default input context. In isolation this can suggest a fixed language/locale assumption without stating that users may provide other languages or timezones.

Missing User Warnings

Low
Confidence
84% confidence
Finding
This markdown file describes cancelling reminders via DELETE and rotating ICS feed tokens, which can affect user access and reminder state. The document provides the mechanics of these operations but does not warn that deleting cancels a reminder or that rotating the feed token invalidates existing calendar subscriptions.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The guidance and examples are entirely in Chinese, and line L06 instructs use of the active locale timezone without any indication that users can choose language or locale handling. Under the policy, forcing a specific language or locale without opt-in can be a natural-language policy violation.

Context-Inappropriate Capability

Low
Confidence
80% confidence
Finding
The manifest frames this skill as performing reminder CRUD and feed-token rotation operations, but the code additionally depends on direct access to process environment variables for REMINDER_API_BASE_URL and REMINDER_API_TOKEN. Reading runtime secrets is a capability beyond the user-facing reminder intent and is not mentioned in the stated scope.

Static analysis

No suspicious patterns detected.