Back to skill

Security audit

Toggle

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent productivity-tracking purpose, but it handles detailed work-history data too broadly and stores or prints raw sensitive activity records.

Review this skill carefully before installing. It is not clearly malicious, but it is designed to collect, retain, and proactively reuse detailed work activity. Only use it if you are comfortable with local long-term storage of raw activity data, and avoid enabling cron or prediction features unless you trust the ToggleX data source and have clear retention controls.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/toggle.py:151
Finding

Unredacted Sensitive Activity Data Is Printed and Persisted in Plaintext

Content
View full analysis
dict: url = f"{API_BASE}?fromDate={from_date}&toDate={to_date}" req = Request(url, headers={ "accept": "application/json", "x-openclaw-api-key": api_key, }) try: with urlopen(req) as resp: return json.loads(resp.read().decode()) ``` ```python def build_toggle_section(day_data: list) -> str: return ( f"{TOGGLE_START}\n" f"## Toggle Activity\n\n" f"```json\n{json.dumps(day_data, indent=2)}\n```\n" f"{TOGGLE_END}" ) def persist_day(memory_dir: str, day: str, workflows: list): path = os.path.join(memory_dir, f"{day}.md") section = build_toggle_section(workflows) if os.path.exists(path): with open(path, "r") as f: content = f.read() pattern = re.compile( rf"{re.escape(TOGGLE_START)}.*?{re.escape(TOGGLE_END)}", re.DOTALL, ) if pattern.search(content): content = pattern.sub(lambda _: section, content) else: content = content.rstrip() + "\n\n" + section + "\n" else: content = f"# {day}\n\n{section}\n" with open(path, "w") as f: f.write(content) ``` ```python data = fetch(api_key, args.from_date, args.to_date) print(json.dumps(data, indent=2)) if args.persist: memory_dir = args.persist os.makedirs(memory_dir, exist_ok=True) workflows_by_date = data.get("workflowsByDate", {}) if not workflows_by_date: print("No workflow data to persist.", file=sys.stderr) return for day, workflows in workflows_by_date.items(): persist_day(memory_dir, day, workflows) ``` Th ...[truncated 3312 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/toggle.py:164
Finding

Unvalidated API-Controlled Date Key Enables Path Traversal During Persistence

Content
View full analysis
Remediation
View remediation
str: parsed = date.fromisoformat(value) normalized = parsed.isoformat() if value != normalized: raise ValueError("Invalid workflow date") return normalized ``` 2. Resolve and enforce destination containment: ```python base = Path(memory_dir).resolve() safe_day = validate_day(day) destination = (base / f"{safe_day}.md").resolve() if destination.parent != base: raise ValueError("Destination escapes memory directory") ``` 3. Defend against symlink-based escapes. - Reject a destination if it is a symlink. - Where supported, open files with flags that prevent following symlinks. - Verify the resolved parent immediately before writing. 4. Use atomic writes. - Create a temporary file inside the validated destination directory. - Apply restrictive permissions. - Flush and atomically replace the destination only after successful serialization. 5. Validate the response schema. - Require `workflowsByDate` to be an object. - Require each key to match strict `YYYY-MM-DD` syntax. - Require each value to be a list with expected field types. - Reject the entire response or skip invalid entries rather than attempting to persist them. 6. Add regression tests for: - `../` and nested traversal sequences. - Absolute paths. - malformed and non-canonical dates. - symlink destinations. - existing files with and without Toggle markers. - destinations outside the selected memory directory. ]]>
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 (13)

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The activation guidance is extremely broad, covering common phrases like 'today', 'tasks', 'time', and 'anything work-related', which can cause unintended invocation in ordinary conversations. Because this skill can fetch and persist sensitive behavioral data, accidental activation materially increases privacy and consent risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill requires environment access, network calls, and read/write access to memory/state files, but it does not declare an explicit tool scope or permissions boundary. That makes it harder for the host or user to understand and constrain what the skill can do, especially given that it fetches remote activity data and persists it locally.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The instruction to use the skill 'PROACTIVELY' is vague and does not define clear boundaries for when autonomous use is appropriate. In context, that ambiguity is risky because the skill is authorized to collect, analyze, and store detailed work-history data without a contemporaneous user request.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to persist fetched activity data into memory files, but the description does not present this as a prominent user-facing warning or consent requirement. Users may not realize that detailed work behavior is being stored across interactions, increasing privacy and retention risk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Saving raw activity data into dated memory files creates a standing log of the user's browsing and work behavior, which may include sensitive metadata and inferred context. Persistent storage increases exposure in case of overbroad access, later misuse, or unintended cross-skill reuse.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly instructs the agent to proactively collect, persist, and reuse detailed activity history without requiring a fresh user request each time. This creates continuous behavioral surveillance and longitudinal profiling risk, especially if enabled by cron jobs.

Content

No source excerpt is available for this finding.

Behavior Manipulation

Medium
Category
Prompt Injection
Confidence
84% confidence
Finding

The instruction to 'silently skip' and 'never tell the user' about insufficient predictive data encourages opaque behavioral modeling. In a system that tries to anticipate user actions, hiding when predictions are being considered or withheld reduces transparency and can normalize covert personalization.

Content

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

md
This is the highest-value behavior. The agent doesn't just know what the user *did* — with enough history, it knows what they're *about to do* and can prepare for it.

**Minimum data required:** `prediction_min_days` days of persisted memory (default: 5). Do NOT attempt predictions with less data — you'll guess wrong and lose trust. When insufficient data exists, silently skip. Never tell the user "I don't have enough data to predict yet."

### 6a. Routine Prediction — "You usually do X right now"

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill directs the agent to mine historical memory files to infer routines, transitions, and predictions from accumulated behavior over multiple days. This is a form of profiling that can reveal work habits and sensitive patterns beyond the user's immediate request.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

The skill is designed to autonomously generate pre-meeting briefings by combining calendar context with past activity, without asking the user first. While useful, this grants the agent discretion to synthesize and surface sensitive work history proactively, which can surprise users or expose context at the wrong time.

Content

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

md
> You have "Wallet App Sync" in 20 minutes. This week you worked on: TON integration (2.1h), FATF compliance research (1.3h), and the auth bug fix (45 min). Want me to draft quick talking points?

**Rules:**
- Only trigger if a calendar skill is available. Do not ask the user about their schedule — that defeats the purpose.
- Only brief if there's actual Toggle data to cross-reference. An empty briefing ("you have a meeting in 20 min") adds no value.
- Maximum 1 briefing per meeting. Deliver it 15–30 minutes before, not 2 hours before.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The guidance 'Never announce internal operations' discourages transparency about monitoring, fetching, and analyzing user activity. In a skill centered on behavioral tracking, suppressing disclosure can prevent meaningful user awareness and consent around sensitive data use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script prints the full fetched workflow JSON to stdout, which can expose sensitive activity history, project names, URLs, timestamps, or other behavioral data to logs, calling processes, or chat surfaces that capture command output. In the context of a productivity/context skill, this data is especially privacy-sensitive because it reflects the user's work patterns and browsing activity.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes capabilities such as generating digests, detecting stale projects, spotting routines, predicting next actions, and answering recall questions from memory. In this implementation, the code only retrieves workflow data from a Toggle endpoint, prints the raw JSON, and optionally persists it verbatim into per-day markdown files, with no analysis or proactive behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The stated purpose centers on capturing and recalling user work sessions and productivity context. This script additionally reads ~/.openclaw/cron/jobs.json and gates execution based on cron configuration, which is an agent-environment management capability rather than an obvious requirement for retrieving Toggle activity data.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.