Back to skill

Security audit

Gcalcli

Security checks for vulnerabilities and agentic risk

Overview

This skill is a calendar helper, but it tells agents to run unpinned remote code and bulk-export sensitive meeting artifacts with unsafe shell commands.

Review before installing. Only use this skill with calendars and meeting artifacts you are authorized to access, avoid the bulk-export examples unless you have explicit approval, pin the gcalcli fork to a reviewed commit or use an official release, and replace the sh -c pipeline with a safer argument-passing or scripted export flow.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:14
Finding

Execution of an Unpinned Mutable Remote Repository

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:14-17
Vulnerability Type: Remote supply-chain code execution
Risk Level: High

Vulnerable Code

bash
**IMPORTANT: Always use the custom fork with attachment support:**
```bash
uvx --from "git+https://github.com/shanemcd/gcalcli@attachments-in-tsv-and-json" --with "google-api-core<2.28.0" gcalcli
text

Equivalent mutable-repository commands are repeated throughout `SKILL.md`.

### Technical Analysis

The skill directs users and agents to retrieve and execute Python code directly from the mutable `attachments-in-tsv-and-json` branch of a personal GitHub fork. The reference is not pinned to a reviewed commit hash, signed release, immutable artifact, or verified checksum.

Consequently, the effective code executed by `uvx` can change after the skill has been reviewed. A repository owner, compromised maintainer account, malicious collaborator, or attacker who compromises the repository can replace the branch contents. The modified package would then execute locally whenever one of the documented commands is invoked.

The dependency also operates in a sensitive context: it initiates Google OAuth authentication, accesses calendar information, and may receive event descriptions, attendee information, conference links, and attachment URLs. Although the version constraint on `google-api-core` limits its version, it does not provide integrity protection for the primary Git dependency.

### Attack Path

1. An attacker compromises the custom fork, its maintainer account, or the referenced branch.
2. The attacker modifies the branch to include malicious Python code in package initialization or command execution paths.
3. A user or agent follows the skill and runs the documented `uvx --from git+https://...` command.
4. `uvx` retrieves the current branch contents and executes them with the invoking user's privileges.
5. The malicious code can access data and res
...[truncated 1060 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer an audited official gcalcli release that contains the required functionality.
  2. If the fork is unavoidable, pin it to a specific reviewed commit hash rather than a mutable branch:
    bash
    uvx --from "git+https://github.com/shanemcd/gcalcli@<reviewed-commit-hash>" \
      --with "google-api-core<2.28.0" gcalcli
    
  3. Record the approved commit and review its complete dependency tree before deployment.
  4. Build an immutable wheel from the reviewed source and publish it through a controlled internal package registry.
  5. Verify artifact hashes or signatures during installation.
  6. Apply the same immutable reference to every command example in SKILL.md; do not leave fallback examples that use the mutable branch.
  7. Run the dependency in a sandbox or container with narrowly scoped filesystem and network access.
  8. Request only the minimum Google OAuth scopes required for read-only calendar operations.
  9. Establish a controlled update process in which new commits are reviewed and explicitly approved before the pinned reference is changed.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:130
Finding

Shell Command Injection Through Attachment URL Substitution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:130-135
Vulnerability Type: Shell command injection
Risk Level: High

Vulnerable Code

bash
**Bulk export ALL Gemini notes from search results (parallel):**
```bash
# Extract Gemini note URLs and export in parallel (8 concurrent processes)
cd /var/home/shanemcd/github/shanemcd/gcmd
uvx --from "git+https://github.com/shanemcd/gcalcli@attachments-in-tsv-and-json" --with "google-api-core<2.28.0" gcalcli search "MCP" --calendar smcdonal@redhat.com --details all --json "2 months ago" "today" | jq -r '.[] | select(.attachments[]? | .attachment_title | contains("Notes by Gemini")) | .attachments[] | select(.attachment_title | contains("Notes by Gemini")) | .attachment_url' | sort -u | xargs -P 8 -I {} sh -c 'uv run gcmd export "{}" -o ~/Downloads/meeting-notes/'
text

### Technical Analysis

The pipeline extracts attachment URLs from calendar-derived JSON and substitutes each value directly into a shell program passed to `sh -c`:

```bash
sh -c 'uv run gcmd export "{}" -o ~/Downloads/meeting-notes/'

xargs performs textual replacement of {} before the resulting string is interpreted by the shell. Double quotes around the replacement location do not make this safe because quotation marks, command substitutions, backticks, or other shell syntax contained in the substituted value become part of the shell source code.

For example, a value containing a double quote followed by shell syntax can terminate the intended argument and introduce an additional command. Exploitation requires an attacker to influence an attachment URL or equivalent value returned by the calendar/API processing pipeline. The skill does not validate the URL scheme, hostname, character set, or provenance before evaluating the value through sh -c.

The use of xargs -P 8 also causes up to eight shell processes to run concurrently, which can increase the impact and complicate det ...[truncated 1709 chars]

Remediation
View remediation

Remediation Suggestions

Avoid embedding untrusted values into shell source. Pass each URL as a positional argument instead:

bash
... |
  jq -r '...' |
  sort -u |
  xargs -P 8 -I {} sh -c \
    'uv run gcmd export "$1" -o "$HOME/Downloads/meeting-notes/"' \
    _ '{}'

Positional parameters prevent the URL from being reparsed as part of the shell program. Additional hardening should include:

  1. Validate each value before export and accept only HTTPS URLs.
  2. Restrict hostnames to the exact trusted Google Drive or Google Docs domains required by the workflow.
  3. Reject values containing control characters, line breaks, or malformed URL encoding.
  4. Prefer a Python script or another structured API that passes arguments directly without invoking a shell.
  5. Use null-delimited records if upstream values can contain whitespace or line breaks.
  6. Remove sh -c entirely where possible and invoke the exporter through a wrapper that accepts one URL argument safely.
  7. Reduce or disable parallel execution until input validation and error handling are implemented.
  8. Log rejected URLs without exposing OAuth tokens or sensitive query parameters.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The authentication section understates the effective access by saying it requests calendar read permissions, while later instructions enumerate calendars and access linked attachment URLs that may lead to Drive-hosted content. This can mislead users about the real data exposure and trust boundary, preventing informed consent around access to sensitive meeting artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill provides detailed instructions for extracting attachment URLs, Gemini notes, recordings, and chat transcripts from a personal/work calendar and exporting them, but it gives no privacy, retention, or authorization warning. In context, this is dangerous because meeting artifacts often contain confidential business information, personal data, and internal links that become easy to harvest in machine-readable form.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The instructions emphasize finding and mass-exporting meeting notes, recordings, chat transcripts, and attachment URLs, including parallelized bulk export. In this context, the skill materially lowers the barrier to large-scale collection of sensitive collaboration data from a personal or corporate calendar, increasing insider misuse and accidental data leakage risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill is presented as a calendar interaction tool, but it instructs users to pivot into exporting Drive/Docs-hosted attachments and Gemini meeting notes via a separate gcmd tool and shell pipelines. That expands scope beyond the declared capability into bulk document extraction, which increases the chance of unauthorized collection or oversharing of sensitive meeting notes, recordings, and chats.

Content

No source excerpt is available for this finding.

Unbounded Output

Medium
Category
Output Handling
Confidence
60% confidence
Finding

Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Content

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

md
- Includes attachments array with title and fileUrl for each attachment
- All event fields preserved
- Easy to parse programmatically with `jq` or Python
- No truncation of any fields
- Best for accessing meeting notes and attachments

### --tsv (Tab-Separated Values)

Unbounded Output

Medium
Category
Output Handling
Confidence
60% confidence
Finding

Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Content

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

md
- conference details
  - title
  - location
  - description (full, no truncation)
  - calendar
  - email
  - attachments (pipe-separated: title|url|title|url...)

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

The command uvx gcalcli runs an unpinned package from whatever version is current at execution time, creating a supply-chain risk and making behavior non-reproducible. In this skill, that risk is amplified because the tool is used to access sensitive calendar metadata and attachments, so a compromised or changed package could exfiltrate data or alter outputs.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.