Back to skill

Security audit

Andrew Google Sheets

Security checks for vulnerabilities and agentic risk

Overview

This Google Sheets skill mostly matches its stated purpose, but its OAuth token handling uses unsafe pickle loading that can execute code if the local token file is tampered with.

Install only if you are comfortable with broad Google Sheets access and local OAuth token storage. Prefer replacing pickle token storage with Google's JSON credential serialization before use, pin dependencies, run in a dedicated virtual environment, and require explicit user confirmation before clearing or overwriting spreadsheet ranges.

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:31
Finding

Arbitrary Code Execution Through Unsafe Pickle Deserialization

Content
View full analysis

Vulnerability Details

File Location: scripts/oauth_setup.py, lines 31-33
Vulnerability Type: Unsafe deserialization of a locally stored authentication token
Risk Level: High

Vulnerable Code

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

The affected token path is defined at line 19:

python
TOKEN_FILE = Path.home() / '.google-sheets-token.pickle'

Technical Analysis

Python pickle data is executable serialization rather than a safe data-only format. During pickle.load(), specially constructed objects can invoke arbitrary callables through reconstruction methods such as __reduce__.

The application loads ~/.google-sheets-token.pickle without validating its integrity, ownership, permissions, or provenance. Consequently, the mere existence of a maliciously replaced token file is sufficient to trigger code execution when authenticate() is called. Authentication-dependent operations in both scripts can reach this code path.

Exploitation requires an attacker or compromised local process to obtain write access to the token file or its parent home directory. The vulnerability does not independently provide that initial access, but it converts token-file modification into arbitrary code execution.

Attack Path

  1. An attacker gains the ability to create or replace ~/.google-sheets-token.pickle, such as through another compromised process running as the same user, an insecure backup restoration process, or incorrectly configured file permissions.
  2. The attacker creates a malicious pickle whose reconstruction routine executes an operating-system command.
  3. The victim invokes OAuth setup or any spreadsheet operation that calls authenticate().
  4. The code detects the token file and passes it directly to pickle.load().
  5. The malicious reconstruction routine executes before credential validity is checked.

...[truncated 683 chars]

Remediation
View remediation

Remediation Suggestions

Replace pickle serialization with a non-executable credential format supported by the Google authentication library. For example, save credentials using Credentials.to_json() and restore them using Credentials.from_authorized_user_file().

Additional hardening should include:

  1. Create the token file with permissions restricted to its owner, such as mode 0600.
  2. Verify that the file is a regular file, is owned by the expected user, and is not a symbolic link before reading it.
  3. Write updated credentials atomically through a securely created temporary file in the same directory.
  4. Reject token files with unexpectedly permissive ownership or access modes.
  5. If migration from pickle is necessary, do not automatically deserialize the existing file. Require the user to delete it and complete OAuth authentication again.
  6. Protect the home directory and token path from writes by untrusted users or processes.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:25
Finding

Unpinned Third-Party Dependencies Allow Unreviewed Supply-Chain Changes

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 25-27
Vulnerability Type: Unpinned dependency installation
Risk Level: Medium

Vulnerable Code

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

Technical Analysis

The installation instructions specify package names without fixed versions or integrity hashes. Each installation can therefore resolve to different package and transitive dependency versions.

The named packages are consistent with the libraries imported by the project, and no typosquatted or obviously malicious package was identified. Nevertheless, the mutable resolution process means future releases, compromised upstream artifacts, or unexpected transitive dependency changes can be installed without project-level review.

Python packages may execute code during installation, import, or runtime. An upstream supply-chain compromise could therefore result in arbitrary code execution in the environment where the documented command is run.

Attack Path

  1. An upstream package account, release process, distribution artifact, or transitive dependency is compromised.
  2. A malicious or vulnerable version becomes available through the package index used by pip.
  3. A user follows the documented installation command without version constraints or hash verification.
  4. Pip resolves and installs the affected release.
  5. Malicious code executes during installation or when the OAuth and Sheets scripts import or invoke the dependency.

This path depends on an external supply-chain compromise; the audited project itself does not host or retrieve a known malicious package.

Impact Assessment

A compromised dependency could execute code with the privileges of the user performing installation or running the Skill. It could access local OAuth client credentials, stored Google tokens, spreadsheet data returned through the API, and other files available ...[truncated 320 chars]

Remediation
View remediation

Remediation Suggestions

Use a reviewed and reproducible dependency specification:

  1. Pin direct and transitive dependencies to tested versions in a lock file.
  2. Record cryptographic hashes and install with pip's --require-hashes option.
  3. Install packages inside a dedicated, unprivileged virtual environment.
  4. Explicitly use the intended package index and disallow unexpected supplemental indexes.
  5. Regularly scan locked dependencies for known vulnerabilities and update them through a controlled review process.
  6. Prefer a generated lock file or hashed requirements file over a bare pip install command in the setup documentation.
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 (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

설명은 Google Sheets API를 통한 스프레드시트 읽기/쓰기, 셀 편집/포맷 처리, OAuth 2.0 인증을 중심 기능으로 제시한다. 그러나 제공된 코드 조각의 실제 핵심 기능은 OAuth 설정/토큰 관리와 Drive API를 통한 스프레드시트 파일 목록 조회다. 이는 단순한 인증 보조 구현을 넘어, 선언에 없는 Google Drive 리소스 접근과 파일 메타데이터 열람을 포함한다. 반대로 설명에서 강조한 시트 내용 읽기/쓰기나 서식 조작은 이 코드에서는 구현되지 않았다. 따라서 선언된 목적과 실제 동작 사이에 실질적 불일치가 있다.

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-sheets-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 119)May include surrounding context.

python
# 토큰 저장 경로
TOKEN_FILE = Path.home() / '.google-sheets-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.

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 using pickle.load(), which can execute arbitrary Python code during loading if the file is tampered with. In an agent/skill context, any local attacker, malicious prior process, or compromised environment that can write ~/.google-sheets-token.pickle could achieve code execution the next time authentication runs.

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:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill metadata describes Google Sheets operations, but the code also builds a Drive API client and enumerates spreadsheet files, expanding visibility into the user's Drive contents beyond a narrow Sheets-only expectation. This mismatch is dangerous because users may grant OAuth access under incomplete understanding of what data the skill can inventory and expose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code file includes a function that clears a spreadsheet range, which is a destructive operation affecting user data. Although the docstring names the action, there is no confirmation prompt, visible logging/print disclosure, or explicit warning about data loss before executing the clear request.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The write_range function sends provided cell data to an external service and modifies spreadsheet contents. While writing is part of the function's purpose, the code itself provides no user-facing notice, logging, or warning that data will be transmitted to Google Sheets and persisted remotely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The append_rows function transmits input data to Google Sheets and appends new rows, affecting remote user data. The code contains no print/log statement or confirmation to disclose that external network transmission and persistent modification will occur.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This function performs bulk updates to spreadsheet ranges through the Google Sheets API, which both transmits data externally and changes persisted spreadsheet contents. There is no user-facing warning, confirmation, or logging describing the impact of the batch update.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.