Back to skill

Security audit

google-workspace-rave

Security checks for vulnerabilities and agentic risk

Overview

This skill is purpose-aligned for Google Workspace automation, but it asks agents to handle sensitive OAuth credentials and callbacks through chat and workspace files while granting broad Workspace access.

Review this skill carefully before installing. Use it only with least-privilege Google scopes, avoid pasting OAuth secrets or callback URLs into chat, keep credentials in a secret manager or protected file outside the workspace, and require explicit confirmation plus dry runs before any send, share, admin, or delete action.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:30
Finding

OAuth Secrets and Authorization Callback Exposed Through Chat and Plaintext Workspace Storage

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 30-37
Vulnerability Type: Sensitive credential exposure and insecure secret storage
Risk Level: High

Vulnerable Instructions:

text
1. **Ask for `client_secret.json`:** Prompt the user to provide their Google Cloud OAuth `client_secret.json`. They can either upload the file or paste its contents into the chat. Once they do, save it as `credentials.json` in the workspace.
2. **Explain the Flow:** Once you have the file, explain to the user exactly how the auth will work:
   > *"I have saved your credentials. I am now going to start the authentication process. I'll provide you with a Google login link. You'll need to click it, authorize your account, and then your browser will redirect to a blank `http://localhost...` page. Copy that full localhost URL and paste it back to me here!"*
3. **Run Authentication:** Run `gws auth login` in the background (using your `exec` tool). Extract the generated Google OAuth URL from the output and send it to the user.
4. **Complete Handshake:** When the user replies with the `http://localhost...` callback URL, use `curl` to fetch that exact URL. This completes the local webserver handshake for `gws`. Confirm successful authentication with the user.

Technical Analysis

The mandatory authentication workflow directs the user to upload or paste an OAuth client-secret document into the conversation. This places sensitive authentication material in chat history, agent traces, telemetry, and any systems that retain conversation content.

The Skill then stores the material under the predictable name credentials.json in the workspace. The mandatory workflow does not require restrictive file permissions, storage outside the project, cleanup after authentication, or exclusion from source control. Although another section recommends chmod 600 for an alternative workflow, that safeguard is not incorporated into this workflow. ...[truncated 1717 chars]

Remediation
View remediation

Remediation Suggestions

  • Never request OAuth client secrets, tokens, authorization codes, or complete callback URLs through chat.
  • Prefer a direct browser-based OAuth flow using PKCE or a device authorization flow supported by the provider.
  • Deliver the callback directly to the local OAuth listener without routing it through the agent.
  • Store credentials outside the project workspace in an OS keyring or dedicated secret manager.
  • If a temporary file is unavoidable, create it atomically with mode 0600, use a non-predictable path in a protected directory, and securely remove it immediately after use.
  • Prohibit credential contents from appearing in command output, debug logs, telemetry, or conversation history.
  • Add credential filenames to .gitignore, but do not treat .gitignore as a substitute for secure storage.
  • Request only the minimum OAuth scopes needed for the current user operation.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:35
Finding

Insufficient Validation of a User-Supplied OAuth Callback URL Before Curl Invocation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 35-37
Vulnerability Type: Unvalidated URL fetch and potential loopback service interaction
Risk Level: Medium

Vulnerable Instructions:

text
3. **Run Authentication:** Run `gws auth login` in the background (using your `exec` tool). Extract the generated Google OAuth URL from the output and send it to the user.
4. **Complete Handshake:** When the user replies with the `http://localhost...` callback URL, use `curl` to fetch that exact URL. This completes the local webserver handshake for `gws`. Confirm successful authentication with the user.

Technical Analysis

The Skill tells the agent to fetch a user-supplied URL with curl but does not specify a mandatory validation procedure. Merely describing the expected value as an http://localhost... URL is not equivalent to enforcing:

  • The exact URL scheme
  • A canonical loopback host or IP address
  • The port opened by the active gws auth login process
  • The expected callback path
  • A matching OAuth state value
  • The absence of URL user information or hostname parsing ambiguities
  • Disabled redirect following
  • A request timeout and response-size limit

A crafted URL could cause the agent to contact an unrelated service listening on the loopback interface. If redirects are enabled by the concrete invocation, the request could also be redirected away from the intended local endpoint. Failure to correlate the OAuth state and active listener can additionally create authentication-flow confusion.

Attack Path

  1. The agent starts gws auth login, opening a local callback listener.
  2. The agent asks the user to return a complete callback URL.
  3. A malicious or compromised user supplies a crafted URL targeting another loopback port, path, or ambiguously encoded hostname.
  4. The agent passes the URL to curl without strict parsing and validation.
  5. The request reaches an unintend ...[truncated 1039 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not ask the agent to replay an OAuth callback URL; allow the browser to contact the local OAuth listener directly.
  • If callback replay is unavoidable, parse the URL using a structured URL parser rather than string matching.
  • Allow only the http scheme and an exact canonical loopback address such as 127.0.0.1 or [::1].
  • Require the exact port and callback path generated for the current gws auth login process.
  • Verify that the OAuth state parameter exactly matches the value associated with the active session.
  • Reject URL user information, fragments, malformed encodings, alternate numeric IP representations, and unexpected query parameters.
  • Disable redirects explicitly and apply short connection and total-request timeouts.
  • Terminate the authentication listener and invalidate the flow after one valid callback or any validation failure.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:16
Finding

Unpinned Globally Installed npm Dependency Creates Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 16-19
Vulnerability Type: Mutable and globally installed third-party dependency
Risk Level: Medium

Vulnerable Configuration:

yaml
install:
  - id: gws
    kind: node
    package: "@googleworkspace/cli"
    bins: ["gws"]
    label: "Install Google Workspace CLI (npm)"

The same unsafe installation pattern is presented in SKILL.md line 26 and README.md lines 20-24:

bash
npm install -g @googleworkspace/cli

Technical Analysis

The package name corresponds to the dependency declared by the project, and the audit found no evidence of typosquatting or a deliberately malicious package. However, the dependency has no pinned version or integrity value. Installation therefore resolves to whichever package release is current when the command runs, meaning the effective executable can change after this Skill has been reviewed.

Global npm installation can execute package lifecycle scripts with the permissions of the invoking user and places binaries in a shared environment. The installed CLI subsequently receives OAuth credentials and broad access to Google Workspace data, increasing the impact of an upstream compromise or malicious future release.

Attack Path

  1. The Skill instructs a user or agent to install the latest available @googleworkspace/cli package globally.
  2. A future package release is compromised, malicious, or contains an unexpected security regression.
  3. npm resolves and installs that release because no audited version or integrity digest is specified.
  4. Installation lifecycle behavior or the installed gws binary executes in the user environment.
  5. The altered dependency accesses local files, environment variables, OAuth credentials, or Workspace data available to the CLI.

Impact Assessment

A compromised dependency would execute with the operating-system privileges of the user performing t ...[truncated 492 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin the dependency to a specifically reviewed version, for example @googleworkspace/cli@<reviewed-version>.
  • Verify package provenance, publisher identity, release signatures where available, and npm integrity metadata.
  • Use a lockfile or organizational package policy to prevent silent dependency changes.
  • Install the dependency locally in an isolated project or container rather than globally.
  • Disable npm lifecycle scripts during installation unless they are required and have been audited.
  • Run the CLI under a dedicated least-privileged operating-system account or sandbox.
  • Re-audit dependency updates before changing the pinned version.
  • Restrict the OAuth scopes and local files available to the CLI so a dependency compromise has limited impact.

T09 · Insecure Skill Coding Practices

Warning
Location
references/advanced.md:27
Finding

Destructive Batch Drive Deletion Lacks Confirmation and Dry-Run Enforcement

Content
View full analysis

Vulnerability Details

File Location: references/advanced.md, lines 27-31
Vulnerability Type: Unsafe destructive batch operation
Risk Level: Medium

Vulnerable Example:

bash
# Delete all files in trash
gws drive files list --params '{"q": "trashed=true"}' --page-all \
  | jq -r '.files[].id' \
  | xargs -I{} gws drive files delete --params '{"fileId": "{}"}'

Technical Analysis

This recipe enumerates every trashed Drive file and immediately pipes each identifier into a deletion command. It does not require an explicit user confirmation after resolving the target list, does not execute a dry run, imposes no maximum item count, and provides no backup or export step.

Although SKILL.md separately recommends using --dry-run before destructive operations, this documented batch example does not apply that safeguard. Agents frequently treat examples as executable workflows, so the inconsistency can lead directly to permanent bulk deletion.

The pipeline also lacks an explicit empty-input safeguard such as xargs -r. Behavior varies across environments, and robust destructive workflows should not rely on implementation-specific defaults.

Attack Path

  1. A user or agent selects the documented “Delete all files in trash” recipe.
  2. The first command enumerates every Drive object matching trashed=true across all returned pages.
  3. jq extracts each file identifier.
  4. xargs invokes gws drive files delete for every identifier without presenting the resolved list for approval.
  5. All matching files are permanently deleted before the user can detect an incorrect query, excessive target count, or misunderstanding of the operation.

Impact Assessment

The operation can permanently delete every file currently in the authenticated user’s Google Drive trash. The affected scope may include personal files, shared content that the user is authorized to delete, and a large number of objec ...[truncated 287 chars]

Remediation
View remediation

Remediation Suggestions

  • Resolve and display the complete target list before issuing any deletion request.
  • Require explicit, operation-specific user confirmation that includes the number of affected files.
  • Perform a mandatory --dry-run or equivalent preview before execution.
  • Add a maximum batch size and require additional confirmation when the limit is exceeded.
  • Use an empty-input safeguard such as xargs -r where supported.
  • Prefer a two-phase workflow: export or back up file metadata, then execute deletion only after approval.
  • Record individual outcomes and stop on unexpected errors rather than continuing blindly.
  • Keep destructive and Admin operations behind a separate policy gate from ordinary read-only Workspace actions.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (18)

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

Scanner excerpt · README.md (reported line 36)May include surrounding context.

md
| **Calendar** | Create events, check availability, manage attendees |
| **Sheets** | Read/write cells, append rows, create spreadsheets |
| **Docs** | Create documents, insert/edit text |
| **Chat** | Send messages to spaces |
| **Tasks** | Create/list/manage task lists and tasks |
| **Admin** | User management, directory queries |
| **Meet** | Create meeting spaces, review participants |

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The headless setup instructs users to export unmasked credentials to a local file without any warning about secret handling, file permissions, or secure storage. In an agent context, a plaintext credential file materially increases the chance of credential theft, reuse, or unintended disclosure through logs, backups, shared hosts, or workspace access.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The command gws auth export --unmasked > credentials.json writes live credentials in plaintext to disk. If that file is read by another local user, an agent, malware, backup system, or accidentally committed or shared, an attacker could gain direct access to the user's Google Workspace data and possibly administrative capabilities granted by the exported scopes.

Content

Scanner excerpt · README.md (reported line 60)May include surrounding context.

Export credentials from a desktop machine:

bash
gws auth export --unmasked > credentials.json

Then on your server:

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

Saving uploaded OAuth credentials as credentials.json in the workspace normalizes plaintext secret handling in an agent-accessible area. In multi-tool or multi-step agent pipelines, workspace files may be readable by other components, increasing the blast radius of credential compromise.

Content

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

md
When a user wants to start using this skill or if credentials are missing, **you (the AI agent) MUST follow this specific authentication workflow**:

1. **Ask for `client_secret.json`:** Prompt the user to provide their Google Cloud OAuth `client_secret.json`. They can either upload the file or paste its contents into the chat. Once they do, save it as `credentials.json` in the workspace.
2. **Explain the Flow:** Once you have the file, explain to the user exactly how the auth will work:
   > *"I have saved your credentials. I am now going to start the authentication process. I'll provide you with a Google login link. You'll need to click it, authorize your account, and then your browser will redirect to a blank `http://localhost...` page. Copy that full localhost URL and paste it back to me here!"*
3. **Run Authentication:** Run `gws auth login` in the background (using your `exec` tool). Extract the generated Google OAuth URL from the output and send it to the user.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

Saving uploaded OAuth credentials as credentials.json in the workspace normalizes plaintext secret handling in an agent-accessible area. In multi-tool or multi-step agent pipelines, workspace files may be readable by other components, increasing the blast radius of credential compromise.

Content

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

md
When a user wants to start using this skill or if credentials are missing, **you (the AI agent) MUST follow this specific authentication workflow**:

1. **Ask for `client_secret.json`:** Prompt the user to provide their Google Cloud OAuth `client_secret.json`. They can either upload the file or paste its contents into the chat. Once they do, save it as `credentials.json` in the workspace.
2. **Explain the Flow:** Once you have the file, explain to the user exactly how the auth will work:
   > *"I have saved your credentials. I am now going to start the authentication process. I'll provide you with a Google login link. You'll need to click it, authorize your account, and then your browser will redirect to a blank `http://localhost...` page. Copy that full localhost URL and paste it back to me here!"*
3. **Run Authentication:** Run `gws auth login` in the background (using your `exec` tool). Extract the generated Google OAuth URL from the output and send it to the user.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The instructions explicitly tell users to upload or paste OAuth client secrets into chat, with no strong warning that this is sensitive credential material. Chat channels, logs, agent memory, and workspaces can retain this data, increasing the risk of credential disclosure and unauthorized API access.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The natural-language workflow instructs users to paste both credential file contents and OAuth callback URLs into chat, exposing sensitive authentication material in a medium not designed for secret handling. This is especially risky in agent systems where transcripts may be persisted, inspected, or reused by downstream tools.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The guidance to export unmasked credentials into credentials.json promotes plaintext credential material on disk. While common in CLI workflows, this is risky in shared, ephemeral, or agent-managed environments where files may be indexed, copied, or accidentally exposed.

Content

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

Complete auth on a machine with a browser, then export:

bash
gws auth export --unmasked > credentials.json

Security notes:

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 · README.md (reported line 66)May include surrounding context.

text

> **Security notes:**
> - Set file permissions: `chmod 600 credentials.json`
> - Do not commit credential files to git — add `credentials.json` to your `.gitignore`
> - For production environments, prefer using a service account instead of user credentials

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 · SKILL.md (reported line 65)May include surrounding context.

text

> **Security notes:**
> - Set file permissions: `chmod 600 credentials.json`
> - Do not commit credential files to git — add `credentials.json` to your `.gitignore`
> - For production environments, prefer using a service account instead of user credentials

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 · SKILL.md (reported line 66)May include surrounding context.

text

> **Security notes:**
> - Set file permissions: `chmod 600 credentials.json`
> - Do not commit credential files to git — add `credentials.json` to your `.gitignore`
> - For production environments, prefer using a service account instead of user credentials

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 · SKILL.md (reported line 72)May include surrounding context.

text

> **Security notes:**
> - Set file permissions: `chmod 600 credentials.json`
> - Do not commit credential files to git — add `credentials.json` to your `.gitignore`
> - For production environments, prefer using a service account instead of user credentials

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 · references/advanced.md (reported line 7)May include surrounding context.

md
| Variable | Purpose |
|----------|---------|
| `GOOGLE_WORKSPACE_CLI_TOKEN` | Pre-obtained OAuth access token |
| `GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE` | Path to credentials or service account JSON |
| `GOOGLE_WORKSPACE_CLI_LOG` | Log level: `error`, `warn`, `info`, `debug`, `trace` |

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The markdown states the skill gives an AI agent 'full access to Google Workspace' and covers sensitive services like Gmail, Drive, Admin, and Contacts, but it does not warn that the skill can read, modify, send, or administer user and organizational data. For markdown files, this omission matters because the description should disclose behaviors that may affect user data, privacy, or system integrity.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The activation scope is extremely broad, covering effectively any Google Workspace action across many services. In an agent environment, overbroad routing increases the chance that the skill is invoked for sensitive or destructive operations without narrower intent checks, least-privilege scoping, or service-specific safeguards.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill tells the agent to use curl on a callback URL copied from the user, which is untrusted input that triggers a network request. Even though the intended target is localhost for OAuth completion, this creates SSRF-style behavior and could be abused if a crafted URL points to another host, alternate localhost service, or sensitive local endpoint accessible from the agent runtime.

Content

No source excerpt is available for this finding.

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

text

> **Security notes:**
> - Set file permissions: `chmod 600 credentials.json`
> - Do not commit credential files to git — add `credentials.json` to your `.gitignore`
> - For production environments, prefer using a service account instead of user credentials

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file includes a ready-to-run example that deletes all files in trash, but it does not warn the user that the command performs a bulk destructive action. Under the markdown-file criteria, examples that can affect user data or system integrity should include an explicit warning or caution.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.