Back to skill

Security audit

Sands

Security checks for vulnerabilities and agentic risk

Overview

This calendar skill discloses useful scheduling features, but it also installs silent scheduled self-updates and syncs sensitive calendar facts into another datastore, which users should review carefully before installing.

Install only if you intentionally want this skill to run scheduled calendar automation with OAuth-backed calendar access and to write local journals/logs. Before installing, disable or remove the daily self-update, avoid git reset/clean update paths, require explicit approval for updates, and make Chronicle sync opt-in with category controls for medical, travel, and personal events.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T03 · Remote Payload Retrieval and Execution

Error
Location
references/self-update-sands.md:1
Finding

Unattended Self-Update Installs Mutable Remote Code

Content
View full analysis

Vulnerability Details

File Location: references/self-update-sands.md:1-15
Vulnerability Type: Mutable remote payload retrieval and installation
Risk Level: High

Complete Vulnerable Snippet

markdown
# Sands — Self-Update Procedure

`sands.update` pulls the latest package from GitHub. Runs silently.

1. Read `source:` from frontmatter → extract `{owner}/{repo}` from URL
2. Read local version from frontmatter `metadata.version`
3. Fetch remote version: `gh api "repos/{owner}/{repo}/contents/SKILL.md" --jq '.content' | base64 -d | grep 'version:' | head -1`
4. If remote equals local → stop silently
5. Download and install:
   ```bash
   TMPDIR=$(mktemp -d)
   gh api "repos/{owner}/{repo}/tarball/main" > "$TMPDIR/archive.tar.gz"
   mkdir "$TMPDIR/extracted"
   tar xzf "$TMPDIR/archive.tar.gz" -C "$TMPDIR/extracted" --strip-components=1
   cp -R "$TMPDIR/extracted/"* ./
   rm -rf "$TMPDIR"
   ```

The related local updater in scripts/update.sh:1-5 is:

bash
#!/bin/bash
cd "$(dirname "$0")/.."
git reset --hard HEAD 2>/dev/null
git clean -fd 2>/dev/null
git pull 2>/dev/null

The update is registered as a daily background task by SKILL.md:152-168:

markdown
- [ ] Register cron jobs listed below if not already present (check the platform scheduling registry first)

| Job name | Schedule | Command | Purpose |
|---|---|---|---|
...
| `sands:update` | `0 0 * * *` | `sands.update` | Self-update from GitHub source |

All cron jobs use: `--session isolated --light-context --tz America/Los_Angeles`.

Technical Analysis

The Skill establishes an unattended update channel that retrieves an archive from the mutable main branch and copies its contents directly over the active installation. No immutable commit pin, trusted signature, expected digest, content allowlist, review gate, or per-update approval is required.

The separate shell updater likew ...[truncated 1852 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove unattended installation of updates, especially the daily scheduled self-update.
  2. Require explicit user approval before downloading and activating each update.
  3. Resolve updates to an immutable commit or versioned release rather than a mutable branch.
  4. Verify a trusted cryptographic signature or an independently supplied expected digest before extraction.
  5. Download and extract into a staging directory, reject links and unexpected file types, and validate the complete manifest before installation.
  6. Present the source revision and file diff for review before replacing active files.
  7. Activate a validated update atomically and retain a known-good rollback copy.
  8. Avoid git reset --hard and git clean -fd in the update path because they silently discard local state and can conceal the extent of remote replacement.
  9. Ensure scheduled tasks never execute newly downloaded code until the same approval and verification controls have completed.
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (56)

Self-Modification

High
Category
Rogue Agent
Confidence
90% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · CHANGELOG.md (reported line 64)May include surrounding context.

md
### Added
- Frontmatter fields: source, install (were missing)
- Run completion, Hard boundaries, Self-update, Support file map sections
- sands.journal command
- requires.credentials in skill.json for GOOGLE_PLACES_API_KEY
- New reference files: calendar_config.md, recurring_events.md, conflict_detection.md

Self-Modification

High
Category
Rogue Agent
Confidence
90% confidence
Finding

This changelog entry explicitly states the skill has a sands.update command for self-update from GitHub, which indicates a real self-modification capability. In an agent skill, autonomous code or configuration updates from a remote source are dangerous because they can introduce supply-chain compromise, unreviewed behavior changes, or repository-takeover abuse that alters future agent actions.

Content

Scanner excerpt · CHANGELOG.md (reported line 77)May include surrounding context.

md
### Added
- Background tasks: sands:morning-brief, sands:evening-brief, sands:conflict-scan, sands:travel-check, sands:update
- sands.init command for directory/config/cron setup on first run
- sands.update command for self-update from GitHub

### Fixed
- Missing scheduled_tasks in skill.json

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Persisting travel, medical, and personal calendar events into Chronicle is highly sensitive and not justified by the stated purpose of calendar management alone. This can expose intimate behavioral and health information to another datastore, increasing confidentiality risk and long-term privacy harm if accessed improperly or retained unnecessarily.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README advertises pushing personal, medical, and travel events into Chronicle without any explicit privacy notice or consent language. Because these event categories can reveal sensitive health, location, and personal-life information, undisclosed synchronization materially increases privacy and compliance risk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill presents itself as calendar management but also includes repository update/reset/synchronization behaviors unrelated to that purpose. Hiding maintenance or destructive workspace operations behind a productivity skill increases the chance of unsafe invocation and could enable remote code changes or local data loss under misleading cover.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill presents itself as calendar management but also includes repository update/reset/synchronization behaviors unrelated to that purpose. Hiding maintenance or destructive workspace operations behind a productivity skill increases the chance of unsafe invocation and could enable remote code changes or local data loss under misleading cover.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill presents itself as calendar management but also includes repository update/reset/synchronization behaviors unrelated to that purpose. Hiding maintenance or destructive workspace operations behind a productivity skill increases the chance of unsafe invocation and could enable remote code changes or local data loss under misleading cover.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill presents itself as calendar management but also includes repository update/reset/synchronization behaviors unrelated to that purpose. Hiding maintenance or destructive workspace operations behind a productivity skill increases the chance of unsafe invocation and could enable remote code changes or local data loss under misleading cover.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill presents itself as calendar management but also includes repository update/reset/synchronization behaviors unrelated to that purpose. Hiding maintenance or destructive workspace operations behind a productivity skill increases the chance of unsafe invocation and could enable remote code changes or local data loss under misleading cover.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Pushing medical and personal calendar-derived facts into Chronicle materially expands data sharing beyond ordinary calendar management. This creates privacy and data minimization risks because sensitive event metadata may be persisted into another system without clear per-category consent or necessity.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
98% confidence
Finding

A scheduled self-update job gives the skill an automated path to modify its own code without real-time user review. Combined with public source hosting, this creates a strong supply-chain and persistence risk because compromise of the update source or logic can silently alter future behavior.

Content

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

md
| `sands:evening-brief` | `0 20 * * *` | `sands.briefing.generate` | Tomorrow's schedule brief for Vesper |
| `sands:conflict-scan` | `0 7 * * *` | `sands.schedule.conflicts` | Daily conflict scan for upcoming 7 days |
| `sands:travel-check` | `0 7 * * *` | `sands.logistics.travel` | Check next day's events for missing travel blocks |
| `sands:update` | `0 0 * * *` | `sands.update` | Self-update from GitHub source |
| `sands:chronicle-sync` | `0 8 * * 0` | `sands.chronicle.sync` | Weekly calendar → Chronicle fact sync (Sundays 8 AM) |

All cron jobs use: `--session isolated --light-context --tz America/Los_Angeles`.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

The dedicated self-update section confirms intentional support for self-modification, which is especially risky in an agent skill that also has file and scheduling capabilities. Self-modifying components are harder to audit and can change trust boundaries after deployment.

Content

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

md
Registration during `sands.init`:
Check the platform scheduling registry for existing tasks before registering each job. Tasks are declared in SKILL.md frontmatter `metadata.{platform}.cron`.

## Self-Update

See `references/self-update-sands.md`.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

Referencing a self-update workflow as a normal supported operation normalizes remote mutation of the skill. That increases the likelihood that routine execution paths can eventually trigger or rely on behavior that was not present during original review.

Content

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

md
## Self-Update

See `references/self-update-sands.md`.

## Visibility

Self-Modification

High
Category
Rogue Agent
Confidence
96% confidence
Finding

Including self-update guidance in the support file map embeds remote code mutation into the expected operating model of the skill. This broadens the attack surface and undermines reproducibility because behavior may change based on fetched content rather than the reviewed package.

Content

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

md
| `references/preparation_signals.md` | Before sands.briefing.generate |
| `references/travel_time_logic.md` | Before sands.logistics.travel |
| `references/vesper_emit_format.md` | Before sands.briefing.generate; formatting payload for Vesper |
| `references/self-update-sands.md` | Before running sands.update |
| `references/direct_calendar_access.md` | When MCP Google Workspace tools are unavailable; direct Python fallback pattern |
| `scripts/conflict_scan_template.py` | Reusable cron-compatible conflict scan script with multi-account OAuth fallback |
| `references/chronicle_sync.md` | Before sands.chronicle.sync; event classification rules, value format, ingest script path, cron auth pattern, classification pitfalls |

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document explicitly instructs the calendar skill to push user calendar events into Chronicle as persistent facts, expanding a scheduling capability into long-term memory ingestion. Because the synced content includes travel, medical appointments, and personal events, this creates a sensitive-data persistence path that exceeds core calendar management and can expose highly private information if triggered without clear user consent and data-governance controls.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The sync scope includes medical appointments, travel, and significant personal events, all of which are sensitive personal data categories, yet the document provides no explicit privacy notice, consent step, or warning about long-term persistence. This omission is dangerous because users may reasonably expect calendar management, not extraction and archival of health and life-event facts into another system.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The deduplication section states that prior facts are deactivated before re-import, which is a destructive state transition that can silently remove or replace existing memory records if the batch is incomplete, misclassified, or corrupted. Without a clear warning or transactional safeguards, a bad sync could erase valid facts or rewrite the user's long-term memory state incorrectly.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

These instructions direct the agent to perform direct database-writing ingestion into Chronicle, including deactivating and re-importing prior facts, which is outside normal calendar CRUD operations. A calendar skill with authority to write durable memory records creates an unnecessary privilege expansion and enables sensitive event data to be transformed into long-lived database state with limited user visibility.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
99% confidence
Finding

The file explicitly documents self-modification behavior: downloading an archive and copying extracted contents over the current directory. Self-modifying or self-replacing behavior is dangerous because it enables persistence, bypasses normal review/deployment controls, and can convert an otherwise limited skill into a vehicle for untrusted code changes.

Content

Scanner excerpt · references/self-update-sands.md (reported line 1)May include surrounding context.

md
# Sands — Self-Update Procedure

`sands.update` pulls the latest package from GitHub. Runs silently.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The document defines a self-update mechanism that fetches code from GitHub and overwrites local skill files, which is unrelated to the stated calendar-management purpose. This introduces a software supply chain and arbitrary local modification capability into a non-admin skill, increasing the chance of unauthorized code replacement or persistence if the repository, source metadata, or update path is tampered with.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Allowing the skill to pull a tarball from GitHub and install it locally gives the skill an unjustified code acquisition and replacement capability. In the context of a calendar skill, this is especially suspicious because it expands the trust boundary far beyond scheduling operations and could be abused to introduce malicious instructions or alter behavior persistently.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The procedure performs a silent network fetch followed by local file overwrite with no warning, confirmation, or review step. Silent updates remove an opportunity to detect abuse and make compromise of the upstream repo, branch, or parsed source location immediately impactful on the local installation.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Using 'git reset --hard' forcefully discards local tracked changes without confirmation, which can destroy data and operational state. In combination with the surrounding cleanup and pull commands, it enables silent rollback/replacement of the working tree, which is especially dangerous in an agent environment where users expect calendar actions, not repository mutation.

Content

Scanner excerpt · scripts/update.sh (reported line 3)May include surrounding context.

sh
#!/bin/bash
cd "$(dirname "$0")/.."
git reset --hard HEAD 2>/dev/null
git clean -fd 2>/dev/null
git pull 2>/dev/null

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README highlights destructive and state-changing operations such as modify, delete, undo, syncing, and automatic travel event insertion without clearly warning that these actions can alter user data. In a calendar context, silent or poorly disclosed mutations can cause missed meetings, confusing state changes, and unintended propagation of sensitive schedule information.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README advertises capabilities that exceed the stated calendar-management scope: run journaling, self-updating from GitHub, and syncing user events into Chronicle. These features expand the skill's authority into persistence, code supply-chain modification, and cross-system data propagation, creating unnecessary attack surface and increasing the risk of privacy leakage or unauthorized behavior.

Content

No source excerpt is available for this finding.