Back to skill

Security audit

gogcli-mcp-gmail

Security checks for vulnerabilities and agentic risk

Overview

This Gmail skill is mostly coherent and disclosed, but it needs review because some destructive Gmail settings and draft deletions can run without a user-bound confirmation step.

Install only if you are comfortable giving an agent broad Gmail authority, including sending mail, modifying labels and filters, changing aliases, exporting attachments, and storing long-lived Gmail auth. Prefer read-only mode for inspection-only use, keep GOG_FILE_ROOTS narrow, avoid signed attachment links for sensitive files unless needed, and manually confirm any draft, label, filter, or send-as deletion request before allowing the agent to call it.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
src/tools/gmail-extra.ts:3069
Finding

Destructive Gmail deletion tools bypass user-bound confirmation

Content
View full analysis

Vulnerability Details

File Location: src/tools/gmail-extra.ts:3069-3078, src/tools/gmail-extra.ts:3581-3591, src/tools/gmail-extra.ts:4132-4141, and src/tools/gmail-extra.ts:4230-4239
Vulnerability Type: Missing user-bound confirmation for destructive operations
Risk Level: Medium

The corresponding behavior is also included in the executable bundle at dist/index.js.

Vulnerable Code

Draft deletion accepts a model-supplied force Boolean and then delegates directly to the destructive command:

ts
server.registerTool('gog_gmail_drafts_delete', {
  description: 'Permanently delete a Gmail draft (not reversible — drafts do not go to Trash). Requires force:true to delete non-interactively.',
  annotations: { destructiveHint: true, openWorldHint: true },
  inputSchema: z.object({
    draftId: z.string().describe('Draft ID'),
    force: z.boolean().optional().describe('Required to delete in this non-interactive context — without it the delete is refused as a safety guard.'),
    account: accountParam,
  }),
}, async ({ draftId, account, force }) => {
  const args: GogArg[] = ['gmail', 'drafts', 'delete', pos(draftId)];
  if (force) args.push('--force');
  return runOrDiagnose(args, { account });
});

Label, filter, and send-as deletion append --force automatically without invoking the project’s host-mediated confirmation mechanism:

ts
return runOrDiagnose(
  ['gmail', 'labels', 'delete', pos(labelIdOrName), '--force'],
  { account },
);
ts
return runOrDiagnose(
  ['gmail', 'settings', 'filters', 'delete', pos(filterId), '--force'],
  { account },
);
ts
return runOrDiagnose(
  ['gmail', 'settings', 'sendas', 'delete', pos(email), '--force'],
  { account },
);

Technical Analysis

The project already implements user-bound confirmation controls for sensitive actions such as permanent batch deletion, sending mail, enabling vacation responses, creating forwarding filters, and creating sen ...[truncated 2418 chars]

Remediation
View remediation

Remediation Suggestions

  1. Apply requireDispatchConfirmation to every destructive deletion tool before constructing or executing a forced command.
  2. Display an exact-target preview containing the draft, label, filter, or send-as identity that will be deleted.
  3. Bind fallback confirmation tokens to the account, tool name, target identifier, and current target state so approval cannot be replayed for a different object.
  4. Refuse the operation when the MCP host cannot provide confirmation, rather than treating a model-supplied force value as user consent.
  5. Append --force only after successful user confirmation.
  6. Re-fetch the target before execution where practical and reject the operation if its identity or relevant state changed after confirmation.
  7. Add regression tests proving that:
    • The first invocation cannot delete anything.
    • Unsupported confirmation returns an error without calling gog.
    • Rejected confirmation performs no deletion.
    • A token for one target cannot authorize another target.
    • --force appears only on the post-confirmation execution path.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (75)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as Gmail-focused and 'auth and Gmail tools only,' but the documented attachment handling explicitly allows server-side file writes, Drive upload, and signed URL publication. Those capabilities materially expand data exposure beyond ordinary mailbox actions and can leak sensitive attachments outside Gmail's access controls.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · dist/index.js (reported line 43)May include surrounding context.

js
../node_modules/@chrischall/mcp-utils/dist/caller/index.js
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
var storage2 = new AsyncLocalStorage2();
function withCallerCapabilities(capabilities, fn) {
  return capabilities ? storage2.run(capabilities, fn) : fn();
}
function currentCallerCapabilities() {
  return storage2.getStore();
}
var ENVELOPE_CAPABILITIES_KEY = "io.modelcontextprotocol/clientCapabilities";
var ELICITATION_MODES = ["form", "url"];
function isRecord(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function callerCapabilities(ctx) {
  const envelope = isRecord(ctx) && isRecord(ctx.mcpReq) ? ctx.mcpReq.envelope : void 0;
  if (isRecord(envelope)) {
    const declared = envelope[ENVELOPE_CAPABILITIES_KEY];
    if (isRecord(declared))
      return declared;
  }
  return currentCallerCapabilities();
}
function callerAcceptsFormElicitation(ctx) {
  const capabilities = callerCapabilities(ctx);
  if (!capa

YARA rule 'exploit_framework': Exploit framework components and payloads [hacktools]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · dist/index.js (reported line 18139)May include surrounding context.

js
ams);
}
function keyof(schema) {
  const shape = schema._zod.def.shape;
  return _enum2(Object.keys(shape));
}
var ZodObject = /* @__PURE__ */ $constructor("ZodObject", (inst, def) => {
  _ensureDefaultMemoizer();
  $ZodObjectJIT.init(inst, def);
  ZodType.init(inst, def);
  inst._zod.processJSONSchema = (ctx, json2, params) => objectProcessor(inst, ctx, json2, params);
  util_exports.installLazyProp(inst, "shape", (self) => self._zod.def.shape, false);
}, {
  keyof() {
    return _enum2(Object.keys(this._zod.def.shape));
  },
  catchall(catchall) {
    return this.clone(util_exports.mergeDefs(this._zod.def, { catchall }));
  },
  passthrough() {
    return this.clone(util_exports.mergeDefs(this._zod.def, { catchall: unknown() }));
  },
  loose() {
    return this.clone(util_exports.mergeDefs(this._zod.def, { catchall: unknown() }));
  },
  strict() {
    return this.clone(util_exports.mergeDefs(this._zod.def, { catchall: never() }));
  },
  strip() {
    return this.clone(util_exports

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · dist/index.js (reported line 27088)May include surrounding context.

js
function validateAsync3() {
      const ruleErrs = gen.let("ruleErrs", null);
      gen.try(() => assignValid((0, codegen_1._)`await `), (e) => gen.assign(valid, false).if((0, codegen_1._)`${e} instanceof ${it.ValidationError}`, () => gen.assign(ruleErrs, (0, codegen_1._)`${e}.errors`), () => gen.throw(e)));
      return ruleErrs;
    }
    function validateSync() {
      const validateErrs = (0, codegen_1._)`${validateRef}.errors`;

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · dist/index.js (reported line 33507)May include surrounding context.

js
if (typeof promptName !== "string") return;
        const prompt = this._registeredPrompts[promptName];
        if (prompt === void 0 || !prompt.enabled) return;
        return prompt.scopeChallenge?.(context);
      }
      default:
        return;

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · dist/index.js (reported line 33709)May include surrounding context.

js
if (typeof promptName !== "string") return;
        const prompt = this._registeredPrompts[promptName];
        if (prompt === void 0 || !prompt.enabled) return;
        return prompt.scopeChallenge?.(context);
      }
      default:
        return;

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · dist/index.js (reported line 34642)May include surrounding context.

js
return walk(value, keep, drop);
}
function normalizeRules(rules) {
  return rules.map((rule) => typeof rule === "string" ? rule.toLowerCase() : new RegExp(rule.source, rule.flags));
}
function matchesRule(key, rules) {
  const lower = key.toLowerCase();

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The bundled code exposes tooling far beyond Gmail, including auth and references to other Google product capabilities, which conflicts with the skill’s declared Gmail-only scope. In an agent setting, scope mismatch is dangerous because a caller or orchestrator may invoke capabilities the user did not intend to grant, expanding the blast radius from mailbox actions to broader Google account access.

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 · dist/index.js (reported line 35806)May include surrounding context.

js
var TOKEN_LEFT_BOUNDARY = "(?<![A-Za-z0-9+/])";
var GOOGLE_TOKEN_PATTERNS = [
  new RegExp(`${TOKEN_LEFT_BOUNDARY}ya29\\.[A-Za-z0-9._\\-]+`, "g"),
  // OAuth2 access tokens
  new RegExp(`${TOKEN_LEFT_BOUNDARY}1//[A-Za-z0-9._\\-]+`, "g")
  // OAuth2 refresh tokens
];

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

The manifest states that a long-lived Google refresh token is imported into a persistent keyring under $HOME and may survive restarts through state.dataDir. In a connector that supports broad Gmail actions, compromise of that persistent store could enable ongoing mailbox access well beyond a single session.

Content

Scanner excerpt · mint.yaml (reported line 34)May include surrounding context.

yaml
required: false
    help: >-
      Google OAuth refresh token (`gog auth tokens export` prints one). Imported
      into gog's keyring at startup with GOG_CLIENT_ID; stripped from the
      spawned CLI's environment by runner.ts's *_TOKEN rule. Changing it
      re-imports on the next start; an in-connector re-auth
      (gog_auth_add_url/complete) stays in effect until it changes.

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 · mint.yaml (reported line 51)May include surrounding context.

yaml
The Google account to act as. Required for the startup auth bootstrap
      (the refresh token is imported under this email); otherwise defaults to
      gog's single/most recent account.
  - name: GOG_KEYRING_BACKEND
    required: false
    help: >-
      gog's credential store. Set to "file" on a headless host — there is no OS

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

This finding concerns the same file-backed persistent keyring design. In context, persistent Gmail OAuth credentials materially expand the blast radius of host compromise because they can enable continued email access and modification.

Content

Scanner excerpt · mint.yaml (reported line 55)May include surrounding context.

yaml
required: false
    help: >-
      gog's credential store. Set to "file" on a headless host — there is no OS
      keychain — so the keyring lives on the persistent data dir.
  - name: GOG_KEYRING_PASSWORD
    secret: true
    required: false

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

This finding concerns the same file-backed persistent keyring design. In context, persistent Gmail OAuth credentials materially expand the blast radius of host compromise because they can enable continued email access and modification.

Content

Scanner excerpt · mint.yaml (reported line 55)May include surrounding context.

yaml
required: false
    help: >-
      gog's credential store. Set to "file" on a headless host — there is no OS
      keychain — so the keyring lives on the persistent data dir.
  - name: GOG_KEYRING_PASSWORD
    secret: true
    required: false

Static analysis

Detected: suspicious.dangerous_exec, suspicious.dynamic_code_execution, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
dist/index.js:35905

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
dist/index.js:27959

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
dist/index.js:35040