Back to skill

Security audit

Andrew Google Calendar

Security checks for vulnerabilities and agentic risk

Overview

The skill matches Google Calendar management, but it uses full calendar access, stores a persistent OAuth token with unsafe pickle deserialization, and can delete or move events without built-in confirmation.

Review before installing. Only use this with a Google account where full calendar read/write access is acceptable, and avoid running it until token storage is changed from pickle to a safer format. Calendar deletes and moves should be wrapped in explicit user confirmation and target preview before use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/oauth_setup.py:27
Finding

Unsafe Deserialization of OAuth Credentials Using Pickle

Content
View full analysis

Vulnerability Details

File Location: scripts/oauth_setup.py, lines 27-29
Vulnerability Type: Unsafe deserialization
Risk Level: High

Vulnerable Code:

python
if TOKEN_FILE.exists():
    with open(TOKEN_FILE, 'rb') as token:
        creds = pickle.load(token)

Technical Analysis

The application deserializes ~/.google-calendar-token.pickle with Python's pickle.load() without validating the file's integrity, ownership, permissions, type, or contents. Pickle is an executable serialization format: specially constructed objects can invoke arbitrary callables during deserialization through mechanisms such as __reduce__.

Merely opening the file and calling pickle.load() is therefore sufficient to execute a malicious payload. The code trusts the token based only on its existence. No signature or other authenticity check establishes that the file was generated by this application.

Exploitation requires the attacker to create, replace, or modify the token file. Possible enabling conditions include another compromised process running as the user, insecure home-directory permissions, an unsafe backup restoration, or another application writing attacker-controlled content to that path.

Attack Path

  1. The attacker obtains the ability to write to or replace ~/.google-calendar-token.pickle.
  2. The attacker creates a malicious pickle whose deserialization routine launches a command or invokes attacker-selected Python code.
  3. The victim invokes any operation that calls authenticate(), including listing or modifying calendar events.
  4. authenticate() finds the token file and passes it directly to pickle.load().
  5. The embedded deserialization payload executes before credential validity is checked.
  6. The payload runs with the operating-system privileges and environment of the user who launched the Skill.

Impact Assessment

Successful exploitation provides arbitrary code execut ...[truncated 607 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace pickle storage with a non-executable format such as JSON.
  • Serialize only the required credential fields and reconstruct credentials with the official Google authentication APIs, for example through Credentials.from_authorized_user_info.
  • Validate the expected JSON schema and reject unknown or incorrectly typed fields.
  • Create the token file atomically with owner-only permissions such as 0600.
  • Before reading, reject symbolic links and verify that the file is a regular file owned by the current user.
  • If tampering by processes with file access is within the threat model, protect the serialized credentials with an operating-system credential store or authenticated encryption.
  • Revoke and reissue existing OAuth tokens if token-file integrity may already have been compromised.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:26
Finding

Unpinned Third-Party Dependencies Installed Without Integrity Verification

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 26-28
Vulnerability Type: Unpinned and unverifiable dependency installation
Risk Level: Medium

Vulnerable Code:

bash
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib

Technical Analysis

The documented setup command installs mutable package versions and their transitive dependencies without a lockfile, exact version constraints, or cryptographic hashes. Consequently, different installations may resolve to different dependency versions depending on when and where setup occurs.

This does not prove that any currently named package is malicious. However, it creates an avoidable supply-chain exposure: a compromised package release, compromised package index, maliciously altered source distribution, or future dependency change could be selected automatically without review.

Python packages can execute code during source-build operations and, once installed, when imported by scripts/oauth_setup.py. The imported Google authentication and API packages operate in a sensitive context containing OAuth credentials and calendar data.

Attack Path

  1. A legitimate package or one of its transitive dependencies publishes or serves a compromised version, or package resolution is otherwise influenced by a compromised index or network configuration.
  2. A user follows the documented unrestricted pip install command.
  3. Pip resolves the affected version because no exact version or hash constraints are supplied.
  4. Malicious code executes during a source build or later when the installed module is imported.
  5. The dependency code inherits the privileges, filesystem access, network access, and environment of the Python process.
  6. It may access OAuth credential files or intercept Google Calendar operations performed through the imported libraries.

Impact Assessment

A compromised dependency could execute arbitrary cod ...[truncated 573 chars]

Remediation
View remediation

Remediation Suggestions

  • Declare direct dependencies with reviewed, exact versions in a requirements or project dependency file.
  • Generate a lockfile that records all transitive dependency versions.
  • Record cryptographic hashes and install with integrity enforcement, such as:
    bash
    python -m pip install --require-hashes -r requirements.txt
    
  • Regenerate and review the lockfile through a controlled dependency-update process.
  • Run dependency vulnerability and provenance checks in continuous integration.
  • Install dependencies inside a dedicated, non-privileged virtual environment rather than using administrator privileges.
  • Configure pip to use only an approved HTTPS package index and avoid untrusted extra indexes.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The overall purpose mostly matches: this code is for Google Calendar OAuth setup and accessing calendar data. However, there are notable undeclared behaviors/capabilities. The code requests full calendar read/write scope (https://www.googleapis.com/auth/calendar) even though this chunk only lists calendars, and it persists credentials/token data to local files in the user's home directory. The description mentions OAuth 2.0 and calendar access/management generally, so the primary purpose is aligned, but these additional capabilities/resources are not clearly represented. Because the evaluation criteria call for flagging undeclared capabilities or inconsistent resource access, this is a mild mismatch rather than a completely different purpose.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/oauth_setup.py (reported line 20)May include surrounding context.

python
# 토큰 저장 경로
TOKEN_FILE = Path.home() / '.google-calendar-token.pickle'
CREDENTIALS_FILE = Path.home() / '.google-credentials.json'


def authenticate():

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/oauth_setup.py (reported line 104)May include surrounding context.

python
# 토큰 저장 경로
TOKEN_FILE = Path.home() / '.google-calendar-token.pickle'
CREDENTIALS_FILE = Path.home() / '.google-credentials.json'


def authenticate():

Ae2

Medium
Category
analysis-evasion
Confidence
90% confidence
Finding

Artifact content does not match its filename extension

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code performs a network API call that transmits potentially sensitive user data such as title, description, location, time, and attendee emails to an external service. While the function docstring describes parameters, it does not provide a user-facing warning, confirmation, or disclosure about the data being sent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

When moving an event to another calendar, the code creates a new event and then attempts to delete the original, suppressing any deletion errors with a bare except. This can lead to unintended data loss, duplication, or silent state corruption, especially if an agent triggers calendar moves without strong user confirmation or if API behavior differs for recurring events.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The delete_event function performs irreversible deletion immediately using only an event ID and returns success without any confirmation, verification, or safety checks. In an agent setting, this makes prompt-injection, user misunderstanding, or identifier mix-ups more dangerous because a mistaken call can destroy calendar data with no built-in guardrail.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code file contains natural-language strings and docstrings exclusively in Korean, including the top-level description and later user-facing runtime messages. Under the policy rule, forcing a specific language without offering user choice or documenting a justified locale constraint is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script requests the broad https://www.googleapis.com/auth/calendar scope, which grants full read/write access to the user's calendars. If the skill only needs limited query/create/manage functionality as suggested by its context, requesting full account-wide calendar access violates least privilege and increases blast radius if the token is stolen or the skill is abused.

Content

No source excerpt is available for this finding.

Insecure deserialization: pickle.load()

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The code deserializes a token file from the user's home directory with pickle.load(), which can execute arbitrary code if that file is replaced or tampered with. In an agent/skill context, local token files are a realistic target because they persist across runs and may be writable or replaceable by other local processes, making this more dangerous than a purely ephemeral script.

Content

Scanner excerpt · scripts/oauth_setup.py (reported line 33)May include surrounding context.

python
# 기존 토큰이 있으면 로드
    if TOKEN_FILE.exists():
        with open(TOKEN_FILE, 'rb') as token:
            creds = pickle.load(token)
    
    # 토큰이 없거나 만료되었으면 새로 인증
    if not creds or not creds.valid:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file uses Korean-language natural-language descriptions and hard-codes the 'Asia/Seoul' time zone for created and updated events. Under the policy, locale-specific behavior should be optional or explicitly justified as region-specific; this file does neither.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.