Back to skill

Security audit

Schedule Manager

Security checks for vulnerabilities and agentic risk

Overview

This schedule skill is useful and mostly transparent, but its Bash command templates can turn task text into local command execution, and its reminder flow passes stored task text into a future agent action.

Install only if you are comfortable with a Chinese-language schedule manager that writes a local schedules/schedule.csv file and can ask another reminder skill to schedule future messages. Do not use untrusted task names or notes until the command templates are changed to structured argument passing instead of Bash interpolation, and review the permissions of cron-mastery before enabling reminders.

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
SKILL.md:23
Finding

Shell Command Injection Through User-Controlled Schedule Fields

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 23-28 and 75
Vulnerability Type: Shell command injection caused by unsafe interpolation of user input
Risk Level: High

Vulnerable Code Snippet

The following is an English rendering of the documented command pattern:

bash
python {baseDir}/scripts/schedule_crud.py add --task "task name" --deadline "YYYY-MM-DD HH:mm" --priority P0 [--note "note"]

The operational workflow repeats the same vulnerable pattern:

bash
python {baseDir}/scripts/schedule_crud.py add --task "..." --priority P0 [--deadline "..."] [--note "..."]

The skill explicitly requires schedule operations to be executed through Bash. Task names, deadlines, and notes originate from user input and are inserted into the command template.

Technical Analysis

Placing untrusted data between double quotes does not make it safe for shell execution. Bash continues to process command substitutions such as $(command) and backticks inside double-quoted strings. An attacker can also include a quotation mark followed by shell control operators to terminate the intended argument and introduce another command.

For example, a task value conceptually equivalent to:

text
$(id > /tmp/schedule-audit-result)

would be evaluated by Bash before Python receives the --task argument. A payload containing a closing quotation mark, a semicolon, and a comment marker could similarly escape the argument context.

The Python implementation does not directly invoke a shell. The vulnerability is introduced by the skill instructions, which mandate Bash execution while providing no structured argument invocation, escaping routine, or restriction against interpolating raw user content.

Attack Path

  1. An attacker asks the agent to create or modify a schedule entry.
  2. The attacker places shell syntax or command substitution in the task name, note, or another interpolated field.

...[truncated 1042 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not build a shell command by concatenating or interpolating user-controlled strings.
  2. Invoke Python through a structured process API using an argument array and with shell processing disabled. The arguments should be passed as separate values, conceptually:
    python
    subprocess.run(
        [
            sys.executable,
            script_path,
            "add",
            "--task",
            task,
            "--deadline",
            deadline,
            "--priority",
            priority,
            "--note",
            note,
        ],
        shell=False,
        check=True,
    )
    
  3. If the agent platform supports typed tool calls, expose schedule operations as typed fields rather than instructing the model to compose Bash.
  4. If Bash cannot be avoided, apply a trusted shell-quoting implementation to every dynamic argument. Do not rely on manually surrounding values with quotation marks.
  5. Add input length and control-character limits as defense in depth, while recognizing that validation is not a substitute for eliminating shell interpretation.
  6. Add regression tests using quotation marks, semicolons, newlines, backticks, dollar-sign command substitutions, and leading option-like values.

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:110
Finding

Stored Prompt Injection Through Scheduled Reminder Content

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 110-117; supporting input storage at scripts/schedule_crud.py, lines 176-180 and 230-246
Vulnerability Type: Stored prompt injection into a future isolated agent turn
Risk Level: Medium

Vulnerable Code Snippet

The following is an English rendering of the complete reminder-construction instruction:

text
1. Ask the user whether a scheduled reminder is required.
2. If the user declines, end the process.
3. If the user confirms, determine the reminder time.
4. Load the cron-mastery skill and create a reminder using agentTurn, announce, and isolated mode:
   DELIVER THIS EXACT MESSAGE TO THE USER WITHOUT MODIFICATION OR COMMENTARY:

   Schedule reminder: [task name] will be due after [remaining time]!
5. Update the reminder status in the schedule record.

The task value inserted into that prompt is stored without content restrictions:

python
new_row = {
    "id": str(next_id(rows)),
    "task": args.task,
    "deadline": args.deadline or "",
    "priority": args.priority,
    "reminder": "N",
    "note": args.note or "",
}

Existing tasks can likewise be replaced with arbitrary input:

python
if args.task is not None:
    target["task"] = args.task
    updated.append("task name")

Technical Analysis

The task name is untrusted content, but the reminder workflow concatenates it into an imperative prompt intended for a future agentTurn. There is no structural separation between the fixed reminder instruction and the user-controlled task content.

Because task names are persisted in CSV, an attacker can include newlines and instruction-like text in a task and leave it stored until a reminder executes. When the reminder prompt is later created, the future agent may interpret the injected text as additional instructions rather than as inert schedule data.

The directive to deliver the message exact ...[truncated 1701 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not concatenate task names into an executable agent instruction.
  2. Pass reminder content through a typed data field or notification API that treats the task name exclusively as display text.
  3. Use a fixed reminder executor that cannot call tools, load additional skills, or reinterpret task content as instructions.
  4. If an agent turn is unavoidable, place untrusted content in an explicitly delimited data structure and instruct the executor to treat that field only as data. Platform-level separation is preferable to prompt-only delimiters.
  5. Reject or encode carriage returns, newlines, and other control characters in task names used for reminders.
  6. Apply reasonable task-name length limits and normalize Unicode before validation.
  7. Escape task text appropriately for the final output channel.
  8. Require confirmation showing the exact rendered reminder before scheduling it.
  9. Add tests using multiline task names, role-like prefixes, instruction-override phrases, delimiter-breaking text, and encoded control characters.
  10. Review the permissions of the external reminder skill and ensure isolated reminder turns have no tools or data access beyond what is strictly required to send a notification.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents file-backed schedule CRUD against schedules/schedule.csv and invokes local scripts, but it declares no explicit tool scope or permission boundaries. Without an allowlist, an agent runtime may grant broader file read/write capability than intended, increasing the chance of unintended filesystem access or abuse if the script behavior changes or user input is mishandled.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases include broad everyday language such as requests to 'remember this' or 'plan tasks,' which can cause accidental invocation. In a skill that performs persistent writes and follow-on actions, overbroad routing raises the risk of unintended schedule creation or modification from ambiguous user conversation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest description and the rest of the file are written entirely in Chinese, and the reminder message is mandated in Chinese with an exact-output requirement. There is no indication that the skill is region-specific or that users may choose another language, which can violate language/locale choice policies.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The routing table maps ambiguous phrases like '完成了XX' and creation-related wording directly to delete/create branches without sufficient specificity. Because these branches can alter or remove persisted user data, ambiguous matching can lead to mistaken destructive actions or unauthorized record changes.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill's stated purpose is schedule/task management, but it silently expands into reminder creation by invoking an additional subflow and external skill. This scope creep is dangerous because it grants extra operational capability beyond what a user may expect from a CRUD-only scheduling skill, increasing the attack surface and the chance of unintended actions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill instructs the agent to load and invoke another skill (cron-mastery) in isolated mode to create reminders, creating an indirect capability escalation path. Chaining into another skill can bypass the original skill's narrower trust assumptions and may enable persistence or scheduled actions the user did not fully authorize.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instruction requires delivering an exact Chinese reminder message "WITHOUT MODIFICATION OR COMMENTARY," leaving no room to adapt to the user's preferred language. This is a direct locale constraint in natural-language instructions without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file title and instructions require replies in a fixed Chinese/plain-text format, and L003 states that all replies must use that format. This imposes a language/locale constraint without any user opt-in or documented justification, which matches the language-policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code embeds user-facing labels and weekday names exclusively in Chinese, and the rest of the CLI messages are likewise fixed to that locale. Because the file does not offer any language selection or state that the tool is intentionally limited to a Chinese-language context, it creates a natural-language locale policy concern.

Content

No source excerpt is available for this finding.