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## 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
## 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
Content
### 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
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.

Self-Modification

High
Category
Rogue Agent
Content
### 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
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.

Context-Inappropriate Capability

High
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.

Missing User Warnings

High
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.

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.

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.

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.

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.

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.

Context-Inappropriate Capability

High
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.

Self-Modification

High
Category
Rogue Agent
Content
| `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`.
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.

Self-Modification

High
Category
Rogue Agent
Content
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`.
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.

Self-Modification

High
Category
Rogue Agent
Content
## Self-Update

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

## Visibility
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.

Self-Modification

High
Category
Rogue Agent
Content
| `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 |
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.

Description-Behavior Mismatch

High
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.

Missing User Warnings

High
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.

Missing User Warnings

High
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.

Context-Inappropriate Capability

High
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.

Self-Modification

High
Category
Rogue Agent
Content
# Sands — Self-Update Procedure

`sands.update` pulls the latest package from GitHub. Runs silently.
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.

Description-Behavior Mismatch

High
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.

Context-Inappropriate Capability

High
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.

Missing User Warnings

High
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.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
#!/bin/bash
cd "$(dirname "$0")/.."
git reset --hard HEAD 2>/dev/null
git clean -fd 2>/dev/null
git pull 2>/dev/null
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.

Missing User Warnings

Medium
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.

Description-Behavior Mismatch

Medium
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.

Static analysis

No suspicious patterns detected.