Back to skill

Security audit

context-switcher

Security checks for vulnerabilities and agentic risk

Overview

The skill is local and mostly purpose-aligned, but its broad automatic activation, silent DND logging, and a path bug that can read or write outside its own folder require review before installation.

Install only if you are comfortable with automatic mode changes affecting notifications and local context. Prefer disabling auto-triggering, avoiding DND silent logging unless explicitly needed, and fixing the package layout/path handling so state and profile files stay inside the context-switcher directory.

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

Warning
Location
switch.sh:10
Finding
Incorrect Base-Directory Resolution Causes Cross-Skill File Access and State Overwrites<![CDATA[ ## Vulnerability Details **File Location**: `switch.sh:10-13`, `switch.sh:65-73`, `switch.sh:88-112`, `restore.sh:10-14`, `restore.sh:39-64`, and `summarize.sh:10-12` **Vulnerability Type**: Improper path resolution and violation of the intended skill-directory boundary **Risk Level**: Medium ### Vulnerable Code `switch.sh`, lines 10-13: ```bash SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" CONTEXT_FILE="$SKILL_DIR/current-context.json" SNAPSHOTS_DIR="$SKILL_DIR/snapshots" MODES_DIR="$SKILL_DIR/modes" ``` `switch.sh`, lines 65-73: ```bash # Create snapshots dir if needed mkdir -p "$SNAPSHOTS_DIR" # Save current state before switching TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") if [[ -f "$CONTEXT_FILE" ]]; then cp "$CONTEXT_FILE" "$SNAPSHOTS_DIR/pre-switch-state.json" fi ``` `switch.sh`, lines 88-112: ```bash # Write new context state cat > "$CONTEXT_FILE" <<EOF { "current_mode": "$MODE", "emoji": "$EMOJI", "activated_at": "$TIMESTAMP", "restore_at": "$RESTORE_AT", "restore_trigger": "$([ -n "$DURATION_MINUTES" ] && echo "timer_${DURATION_MINUTES}min" || echo "manual_or_calendar")", "duration_minutes": "$DURATION_MINUTES", "muted_channels": $([ "$MODE" = "dnd" ] && echo '["all"]' || ([ "$MODE" = "creative" ] && echo '["all"]' || ([ "$MODE" = "work" ] && echo '["personal","social","news"]' || echo '["work_slack","work_email","github"]'))), "session_notes": "" } EOF # Output confirmation for OpenClaw to relay to user echo "$EMOJI Switched to $MODE mode." if [[ -n "$DURATION_MINUTES" ]]; then echo "Auto-restore in ${DURATION_MINUTES} minutes (at ${RESTORE_AT})." fi if [[ -n "$MODE_FILE" && -f "$MODE_FILE" ]]; then echo "" echo "Loading your $MODE profile..." cat "$MODE_FILE" fi ``` `restore.sh`, lines 10-14: ```bash SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" CONTEXT_FILE="$SKILL_DIR/current-context.json" SNAPSHOTS_DIR="$SKILL_DIR/snapshots" DND_LOG="$SNAPSHOTS_DIR/dnd-log.json" PRE_SWI ...[truncated 5160 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Resolve paths relative to the actual checked-in layout. If scripts remain in the project root, use: ```bash SKILL_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" CONTEXT_FILE="$SKILL_DIR/current-context.json" SNAPSHOTS_DIR="$SKILL_DIR/snapshots" ``` 2. Update profile paths to match the supplied layout: ```bash MODE_FILE="$SKILL_DIR/work.md" ``` Alternatively, move the scripts into `scripts/` and profiles into `modes/` so the implementation matches the documented structure. 3. Apply the same corrected base-directory logic consistently in `switch.sh`, `restore.sh`, and `summarize.sh`. 4. Before reading or writing, verify that every resolved path remains inside the canonical package directory. Reject paths that resolve outside it, including through symbolic links. 5. Create state directories with restrictive permissions: ```bash umask 077 mkdir -p -- "$SNAPSHOTS_DIR" chmod 700 -- "$SNAPSHOTS_DIR" ``` 6. Use atomic writes for state files by creating a temporary file inside the package directory, validating its JSON, setting restrictive permissions, and renaming it over the destination. 7. Do not relay arbitrary profile or log contents as trusted agent instructions. Treat these files as untrusted data, delimit them clearly, and ensure the agent is instructed not to interpret embedded text as executable instructions. 8. Add an installation-layout test that invokes each script and asserts that all read and write targets are descendants of the installed `context-switcher` directory. 9. Update `README.md`, `SKILL.md`, and the security manifests to reflect the real package layout and actual files accessed. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Vague Triggers

High
Confidence
96% confidence
Finding
The skill advertises activation from very broad natural-language phrases such as "I need to focus" and "going dark for 2 hours," which are common in ordinary conversation and can be triggered accidentally or through untrusted content. In this skill’s context, a false activation changes assistant behavior, notification filtering, surfaced memory, and DND/logging state, creating a meaningful integrity and privacy risk even without external network access.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior claims broad control over notifications, memory surface, response style, calendar-driven switching, and restore behavior, but the static finding indicates the actual implementation does not perform those controls and instead reads/summarizes local context files. That mismatch is security-relevant because users may grant trust, autonomy, or privacy assumptions based on capabilities the skill does not actually enforce, leading to unsafe reliance and unexpected local data access.

Vague Triggers

High
Confidence
98% confidence
Finding
Do Not Disturb includes very common phrases like 'leave me alone' or 'don't bother me', which may be said casually or quoted. False activation is especially dangerous here because it can mute all notifications and alter responsiveness, potentially causing missed urgent information and silent logging behavior.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The README describes automatic processing of calendar event titles and catch-up/logging behavior, but it does not clearly warn users that calendar metadata and incoming messages may be automatically interpreted, muted, logged, or summarized. Because this skill is specifically designed to reshape memory surface and notification behavior across personal/work contexts, unclear disclosure increases the risk of unexpected privacy exposure, sensitive-context mixing, and user misunderstanding about what data is retained locally.

Vague Triggers

Medium
Confidence
94% confidence
Finding
Advertising autonomous activation from broad 'natural language' and calendar events without strict boundaries creates prompt/trigger ambiguity. In a mode-switching skill, accidental activation can change notification handling, memory loading, and response behavior at the wrong time, causing privacy, integrity, and usability issues.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The auto-invocation note says trigger phrase detection and calendar title matching can invoke the skill, but it gives no guardrails for false positives, scope, or consent. Because this skill can alter how the assistant behaves and what it logs or surfaces, ambiguous autonomous activation is a real safety issue in context.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill mentions autonomous calendar-based switching and DND logging, but the user-facing description does not clearly warn that event titles may be inspected and incoming messages/tasks may be silently recorded. That is a meaningful transparency and privacy issue because users may not understand what local data is being processed or retained.

Vague Triggers

Medium
Confidence
97% confidence
Finding
Several Work/Focus triggers such as common conversational phrases can appear in ordinary discussion and unintentionally activate the skill. Since activation affects notifications and surfaced memory, casual language collisions can disrupt workflows and expose or suppress information unexpectedly.

Vague Triggers

Medium
Confidence
92% confidence
Finding
Calendar keyword matching based on broad terms like 'review', 'planning', or 'appointment' can match ordinary events without user intent to switch modes. Because the skill reacts autonomously to titles alone, it risks unexpected behavior changes and privacy-sensitive context loading from benign calendar metadata.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The Personal mode trigger set includes everyday expressions like being done for the day or off the clock, which are likely to occur naturally. That makes unintended switching plausible, potentially muting work channels or changing assistant behavior without clear user intent.

Vague Triggers

Medium
Confidence
94% confidence
Finding
Creative mode triggers overlap with common ideation language and can be spoken during normal collaboration. Unintended activation could suppress notifications and bias assistant output style toward uncritical ideation when the user did not request it.

Ssd 3

Medium
Confidence
94% confidence
Finding
Silently logging all incoming messages and tasks during DND creates a local surveillance/retention risk, even if data does not leave the machine. In this skill's context, the danger is increased because logging is comprehensive, happens during an intentionally quiet mode, and may capture sensitive work or personal communications without clear contemporaneous notice.

Session Persistence

Medium
Category
Rogue Agent
Content
3. **Apply mode profile** — load the correct `modes/*.md`, apply notification rules, set response style
4. **Confirm switch** with a brief, mode-appropriate message (see Confirmation Messages below)
5. **Set auto-restore** — use calendar event end time, or ask user for duration if unclear
6. **On restore** — un-mute, reload previous state, deliver catch-up summary

---
Confidence
84% confidence
Finding
Saving and reloading previous state introduces session persistence of user context across mode boundaries. In a skill that claims to reshape memory and restore prior state, persistence can unintentionally retain or re-surface sensitive context longer than expected, especially without retention limits, integrity checks, or user review.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The security manifest is inaccurate: the script not only writes current-context.json but also truncates snapshots/dnd-log.json after displaying it. In security-sensitive automation, incomplete disclosure of file writes undermines review, monitoring, and user trust, and can hide state mutation or evidence deletion behavior.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "Restoring from $CURRENT_MODE mode..."

# Restore previous state if snapshot exists
if [[ -f "$PRE_SWITCH" ]]; then
  cp "$PRE_SWITCH" "$CONTEXT_FILE"
  echo "Previous context restored."
Confidence
55% 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.

Ssd 3

Low
Confidence
72% confidence
Finding
The phrase "I'll log everything" reinforces a broad instruction to capture all user communications for later review. This is a plain-language retention directive with clear privacy implications, and its breadth makes it risky even without any external transmission.

Static analysis

No suspicious patterns detected.