Back to skill

Security audit

Gws Skill

Security checks for vulnerabilities and agentic risk

Overview

This Google Workspace skill is coherent and disclosed, but it gives very broad cross-user access to email, files, calendars, contacts, and Vault data without enough built-in authorization guardrails.

Install only in a tightly controlled admin environment after legal/security approval. Use a dedicated least-privilege service account, restrict who can invoke the skill, protect and rotate the JSON key, pin dependencies, require documented case IDs and target users for each query, and avoid full email or Vault exports unless explicitly approved.

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)

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Dependencies Create Supply-Chain Exposure

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-3 and references/setup-checklist.md:65
Vulnerability Type: Unpinned third-party dependencies
Risk Level: Medium

Vulnerable Code

requirements.txt:1-3:

text
google-auth
google-auth-httplib2
google-api-python-client

references/setup-checklist.md:65:

bash
pip3 install google-auth google-auth-httplib2 google-api-python-client

Technical Analysis

The project installs third-party packages without exact version constraints or cryptographic hashes. Each installation therefore resolves the latest release available from the configured Python package index at installation time.

This prevents the audited source tree from defining a reproducible dependency set. A future compromised, malicious, or unexpectedly incompatible release could be installed without changes to this repository. This exposure is especially significant because these dependencies execute in a process that loads a service-account private key and creates credentials with Google Workspace domain-wide delegation.

No currently malicious package was identified in the reviewed files. The vulnerability is the absence of controls that ensure future installations use the reviewed dependency artifacts.

Attack Path

  1. An attacker compromises a maintainer account, distribution infrastructure, or release process for one of the unpinned dependencies.
  2. The attacker publishes a malicious release under the legitimate package name.
  3. An administrator follows the documented setup command or installs from requirements.txt.
  4. Package resolution selects and installs the malicious release because no exact version or hash is required.
  5. The malicious package code executes when imported by the Skill.
  6. It can attempt to read the service-account key, intercept delegated credentials, manipulate API requests, or exfiltrate Google Workspace data.

Impact Asses

...[truncated 621 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to a reviewed exact version, for example with package==version.
  2. Generate a fully resolved lock file that also pins all transitive dependencies.
  3. Record SHA-256 hashes for every permitted distribution artifact.
  4. Install with hash verification, such as:
    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  5. Update the setup checklist to use the locked requirements file rather than installing unconstrained package names.
  6. Review dependency updates before refreshing the lock file and run automated vulnerability and provenance checks.
  7. Use a dedicated virtual environment and a trusted package index configuration.
  8. Run the Skill under a restricted operating-system account that can read only the required credential file and application files.
  9. Prefer short-lived or externally managed service-account credentials where operationally possible, reducing the impact of local key theft.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/vault.py:65
Finding

Unbounded Vault Polling Can Cause Indefinite Execution

Content
View full analysis

Vulnerability Details

File Location: scripts/vault.py:65-70, scripts/vault.py:155-165, and scripts/vault.py:209-214
Vulnerability Type: Missing timeout and retry bounds
Risk Level: Low

Vulnerable Code

scripts/vault.py:65-70:

python
# Poll until complete
while True:
    op = service.operations().get(name=operation["name"]).execute()
    if op.get("done"):
        break
    time.sleep(2)

scripts/vault.py:155-165:

python
# Poll until export is complete
while True:
    exp = service.matters().exports().get(
        matterId=matter_id, exportId=export_id
    ).execute()
    status = exp.get("status", "")
    if status == "COMPLETED":
        return exp
    elif status == "FAILED":
        return {"error": "Export failed", "details": exp}
    time.sleep(5)

scripts/vault.py:209-214:

python
while True:
    op = service.operations().get(name=operation["name"]).execute()
    if op.get("done"):
        break
    time.sleep(2)

Technical Analysis

All three polling loops are unbounded. They have no monotonic deadline, maximum attempt count, cancellation handling, or upper retry duration. The export loop recognizes only COMPLETED and FAILED; an unexpected terminal status can therefore also leave it polling indefinitely.

Although each individual API request may eventually time out, the surrounding loop continues issuing new requests as long as responses do not satisfy the termination condition. This can keep a worker occupied indefinitely and consume API quota.

run_investigation() includes best-effort cleanup in a finally block, but cleanup occurs only after control exits the polling operation. If the process is forcibly terminated to stop a hung operation, cleanup is not guaranteed and the temporary Vault matter or export may remain.

Attack Path

  1. A Vault count or export operation is started.
  2. The remote operati ...[truncated 1315 chars]
Remediation
View remediation

Remediation Suggestions

  1. Establish a monotonic deadline for every polling operation.
  2. Add a configurable maximum number of attempts and maximum total duration.
  3. Use capped exponential backoff with jitter rather than a constant polling interval.
  4. Treat every documented terminal state explicitly and fail safely on unknown terminal states.
  5. Return a structured timeout error containing the matter and operation identifiers needed for investigation.
  6. Attempt to cancel cancellable operations when the deadline expires.
  7. Preserve the existing finally cleanup behavior, but log cleanup failures without exposing credentials or sensitive content.
  8. Add signal handling so normal termination requests trigger cleanup before process exit.
  9. Apply execution-level time limits and concurrency controls in the calling job runner.
  10. Add tests simulating permanently pending operations, unknown statuses, API errors, and cleanup failures.

Example defensive structure:

python
deadline = time.monotonic() + timeout_seconds
delay = 2.0

while time.monotonic() < deadline:
    operation_state = service.operations().get(
        name=operation["name"]
    ).execute()

    if operation_state.get("done"):
        break

    time.sleep(delay)
    delay = min(delay * 2, 30.0)
else:
    raise TimeoutError("Vault operation exceeded its allowed duration")
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (26)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill documentation highlights domain-wide delegation, impersonation, inbox access, Vault search, and document retrieval, but it does not present a prominent warning that these actions expose highly sensitive third-party data and must only be used with explicit authorization. Without that warning, an operator or agent may treat powerful surveillance-style access as routine, leading to privacy violations or unauthorized investigations.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares access to sensitive environment-backed credentials and broad Google Workspace administrative capabilities, but it does not define explicit tool scope boundaries such as allowed tools or permissions. That makes it easier for an agent to invoke the skill in situations beyond the author's intended use, increasing the chance of unauthorized cross-user data access.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description is extremely broad and invites use for many common admin and investigation tasks, including reading any user's email, files, calendars, and documents across the domain. In an agentic environment, this kind of overbroad routing language can cause the skill to be selected for routine requests without sufficient scrutiny of necessity, authorization, or privacy impact.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
74% confidence
Finding

The skill explicitly depends on a persistent service account JSON key stored on disk at a predictable path, which creates a durable authentication artifact that can be reused if the host or account is compromised. Even though the skill claims tokens remain in memory, the long-lived delegated credential materially increases blast radius because it enables broad cross-user access across the Google Workspace domain.

Content

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

md
- **Never log, echo, or output credentials** — service account key and tokens stay in memory only
- **Never send raw email body content to chat unprompted** — always summarize unless explicitly asked for full content
- **Impersonation is logged** — every DWD call specifies which account is being impersonated
- **Read-only access** — no write scopes are granted; cannot send email, create events, or modify files
- **Credential storage** — service account key at `~/.config/gws/service-account.json` (chmod 600, outside any repo)
- **No secrets in code** — key path loaded from env var `GWS_SERVICE_ACCOUNT_PATH` or default path

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
- **Never send raw email body content to chat unprompted** — always summarize unless explicitly asked for full content
- **Impersonation is logged** — every DWD call specifies which account is being impersonated
- **Read-only access** — no write scopes are granted; cannot send email, create events, or modify files
- **Credential storage** — service account key at `~/.config/gws/service-account.json` (chmod 600, outside any repo)
- **No secrets in code** — key path loaded from env var `GWS_SERVICE_ACCOUNT_PATH` or default path

## Auth

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/setup-checklist.md (reported line 38)May include surrounding context.

md
- **Never send raw email body content to chat unprompted** — always summarize unless explicitly asked for full content
- **Impersonation is logged** — every DWD call specifies which account is being impersonated
- **Read-only access** — no write scopes are granted; cannot send email, create events, or modify files
- **Credential storage** — service account key at `~/.config/gws/service-account.json` (chmod 600, outside any repo)
- **No secrets in code** — key path loaded from env var `GWS_SERVICE_ACCOUNT_PATH` or default path

## Auth

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/setup-checklist.md (reported line 7)May include surrounding context.

md
## 1. GCP Project

- Select or create a GCP project
- Enable these APIs:
  - Google Vault API
  - Admin SDK API

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The checklist instructs operators to create and store a service-account JSON key but does not clearly label it as a highly sensitive credential equivalent to privileged API access. In this skill's context, that key enables domain-wide delegation into Google Workspace data, so mishandling or sharing the file could allow broad unauthorized access across mail, Drive, audit logs, and other tenant resources.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The setup authorizes extensive domain-wide delegation scopes, including Vault, Gmail, Drive, Directory, Calendar, Docs, Sheets, and contacts, without warning about the breadth of tenant-wide access being granted. In the context of an admin investigation tool explicitly designed to read any user's inbox and search org-wide content, this omission is dangerous because administrators may enable sweeping access without understanding the surveillance, privacy, and blast-radius implications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code loads a service account JSON key from disk and uses domain-wide delegation with an impersonated subject, which is a sensitive authentication operation. Although there are docstrings describing parameters, the file does not provide any explicit warning, confirmation, or user-facing disclosure about accessing privileged credentials and impersonating an admin account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function returns and the CLI prints detailed Google Workspace directory data, including recovery email, phone numbers, aliases, admin status, suspension state, and 2SV enrollment details, with no access-control checks, purpose limitation, masking, or user-facing warning. In the context of a domain-wide delegation admin/investigation skill, this materially increases privacy and insider-abuse risk because any caller able to invoke the skill can enumerate sensitive identity and security metadata across the organization.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code uses domain-wide delegation to impersonate an arbitrary user and retrieve full Google Docs content, then exposes that content through CLI output with no authorization checks, approval flow, masking, or warning to the operator. In a tool explicitly designed for cross-user Workspace access, that creates a real confidentiality risk because sensitive document data can be read and exfiltrated at scale if the script is invoked by an unauthorized or overly broad workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code uses domain-wide delegation to enumerate a user's Drive files and returns metadata including owners, sharing state, and links for arbitrary impersonated accounts. In the context of an admin/investigation skill, this may be intentional functionality, but it still creates a real privacy and insider-abuse risk because there is no authorization guardrail, scope restriction, audit enforcement, or user/admin disclosure in this module before accessing sensitive per-user Drive data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The metadata retrieval path exposes especially sensitive details such as file permissions, sharing recipients, and descriptions for any specified file under an impersonated user context. That increases the risk of unauthorized surveillance, mapping of confidential collaborations, and leakage of sensitive business context, particularly because the broader skill is explicitly designed for cross-domain Google Workspace investigation via service account delegation.

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 network/API access to retrieve a user's calendar using domain-wide delegation, which can expose sensitive event details, attendees, locations, and descriptions. Although the module docstring mentions read access and impersonation, the executable path provides no user-facing confirmation or warning before retrieving and outputting that data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code performs Gmail API reads against an impersonated user's mailbox, which is a privacy-sensitive network operation involving potentially sensitive user data. Although the module docstring mentions domain-wide delegation, the executable path in main provides no confirmation prompt or user-facing disclosure before returning mailbox contents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The full-read path fetches and returns complete message contents, then prints them to stdout in main, which can expose sensitive personal or business information. The code lacks a user-facing notice or confirmation specifically warning that email bodies will be retrieved and displayed.

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 network calls to the Google People API using domain-wide delegation (impersonate=user) and returns personal contact data such as names, emails, and phone numbers. Although the docstrings mention impersonation, there is no runtime confirmation or explicit user-facing warning before retrieving and disclosing potentially sensitive personal data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code performs a Google Sheets API read using an impersonated user account via domain-wide delegation, which is a privacy-sensitive network operation. While the docstring mentions impersonation, there is no confirmation prompt or explicit user-facing warning at execution time that the tool will access remote spreadsheet data as another user.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This function retrieves spreadsheet metadata through the Google Sheets API while impersonating the provided user, which accesses potentially sensitive remote data. The implementation lacks a visible runtime disclosure or warning to the user beyond internal docstrings.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The batch operation performs network calls to Google Sheets and can retrieve multiple ranges of spreadsheet contents while impersonating a user account. Although this aligns with the script's functionality, there is no visible warning or disclosure to the operator that sensitive remote data may be accessed under delegated identity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The export path enables retrieval of full mailbox content as MBOX from arbitrary accounts or entire investigations without any inline confirmation, warning, approval gate, or narrowing control. In this skill’s context, the capability is explicitly domain-wide and highly sensitive, so lack of friction or explicit user-facing disclosure materially increases the risk of accidental overcollection, misuse, or unauthorized surveillance if the skill is invoked by an over-privileged agent or operator.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency google-auth is unpinned, so installs may pull newer releases with breaking changes or a compromised/transitively vulnerable version. In a high-privilege Google Workspace admin skill that can access mailboxes, audit logs, and files across a domain, supply-chain compromise of this package could expose highly sensitive enterprise data or enable broad unauthorized actions.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
google-auth
google-auth-httplib2
google-api-python-client

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency google-auth-httplib2 is unpinned, which creates a supply-chain risk because future installs can resolve to different versions than were originally tested. Given this skill uses service accounts and domain-wide delegation, any malicious or vulnerable dependency in the auth/HTTP stack could affect authentication flows and access to privileged Google Workspace APIs.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
google-auth
google-auth-httplib2
google-api-python-client

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency google-api-python-client is unpinned, allowing unreviewed versions to be installed later and increasing the chance of supply-chain compromise or unstable behavior. Because this client can interface with Vault, Gmail, Drive, Directory, Calendar, Docs, Sheets, and Reports across the tenant, compromise here could directly enable large-scale data exposure or misuse of administrative capabilities.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
google-auth
google-auth-httplib2
google-api-python-client

Static analysis

No suspicious patterns detected.