Back to skill

Security audit

CDP Gmail Delivery

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent Gmail-sending purpose, but its email automation has unsafe controls that could delete existing drafts or send attachments to the wrong recipient.

Review carefully before installing. Use only in a dedicated Chrome debug profile with no unrelated Gmail drafts open, confirm recipient and attachments manually, avoid sensitive files unless necessary, and prefer a pinned dependency install. The package does not show evidence of intentional theft or deception, but its current automation is too risky for blind 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/send_via_cdp.js:262
Finding

Recipient and Subject Validation Can Produce False Positives Before Sending

Content
View full analysis
(e.getAttribute('email') || '').toLowerCase()); const toValue = (toEl?.value || '').toLowerCase(); const toOk = toValue.includes(to.toLowerCase()) || recipientTokens.includes(to.toLowerCase()) || text.toLowerCase().includes(to.toLowerCase()); const subjectValue = (subEl?.value || '').trim(); const subjectOk = subjectValue.length > 0; const attachmentMatches = requestedFiles.map((name) => ({ name, present: text.includes(name), })); const attachmentOk = attachmentMatches.every((item) => item.present); return { toOk, subjectOk, attachmentOk, attachmentMatches, subjectValue }; }, to, bases); if (!checks.toOk || !checks.subjectOk || !checks.attachmentOk) { throw new Error(`Validation failed: ${JSON.stringify(checks)}`); } ``` ### Technical Analysis The intended recipient is considered valid when its string appears anywhere in the compose dialog. In particular, the following fallback is unsafe: ```javascript text.toLowerCase().includes(to.toLowerCase()) ``` The dialog text includes more than the actual recipient field. It may include the message body, quoted content, attachment metadata, autocomplete content, or unrelated interface text. Consequently, an intended address appearing in the body can make `toOk` true even when the actual recipient chip contains a different address. The check against `toValue` als ...[truncated 1732 chars]
Remediation
View remediation

other

Warning
Location
scripts/send_via_cdp.js:162
Finding

Automatic Draft Discard Can Delete Unrelated User Content

Content
View full analysis
{ const vis = (el) => { if (!el) return false; const r = el.getBoundingClientRect(); const s = getComputedStyle(el); return r.width > 0 && r.height > 0 && s.display !== 'none' && s.visibility !== 'hidden'; }; const discard = [...document.querySelectorAll('div[role="button"][aria-label*="Discard draft"], div[role="button"][aria-label*="捨棄草稿"], div[role="button"][aria-label*="Discard"]')].find(vis); if (discard) discard.click(); }); ``` ### Technical Analysis Before opening a new compose window, the script searches the entire page for the first visible control whose accessible label contains “Discard draft” or “Discard” and clicks it. It does not establish that the draft was created by the current script, inspect whether the draft contains user data, or request confirmation. The broad selector also matches labels containing the generic word “Discard,” increasing the possibility of selecting an unintended destructive control. Because this operation occurs at the start of the workflow, a pre-existing operator-authored draft can be destroyed even if the later email operation fails. Draft deletion is not necessary to perform the declared task of composing and sending a new email. The behavior therefore exceeds the minimum actions required for the workflow. ### Attack Path 1. The operator has a visible unsaved Gmail draft containing user-authored content. 2. The email-delivery script connects to the existing authenticated Chrome session. 3. The script locates the first visible matching discard control across the page. 4. It clicks the control without confirming draft ownership or asking the operator. 5. Gmail deletes the existing draft. ...[truncated 509 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/send_via_cdp.js:101
Finding

Environment-Controlled Module Path Enables Arbitrary Local JavaScript Execution

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/install_runtime.sh:11
Finding

Non-Reproducible npm Installation Exposes the Runtime to Supply-Chain Changes

Content
View full analysis
/dev/null 2>&1 fi npm install --no-fund --no-audit puppeteer-core@24 ``` ### Technical Analysis The installer requests `puppeteer-core@24`, which selects a release from the entire compatible major-version range rather than an exact reviewed version. Installations performed at different times can therefore resolve to different package versions. The project does not provide a lockfile in the audited directory structure, and the installer uses `npm install` rather than a frozen, lockfile-enforcing installation method. No package integrity value is verified. The command also disables npm's audit check and does not disable dependency lifecycle scripts. The package name itself is not a detected typosquat, and the audit found no evidence that the current dependency is malicious. The risk arises from the mutable and non-reproducible installation process. ### Attack Path 1. The operator runs `scripts/install_runtime.sh`. 2. npm resolves the newest package version satisfying the major-version selector `@24`. 3. A future compromised, malicious, or unexpectedly changed compatible release can be selected without any project code changes. 4. npm downloads and installs that release. 5. Any permitted package lifecycle behavior can execute during installation. 6. The installed module is later loaded by the Gmail automation script and runs with the invoking user's privileges. ### Impact Assessment A compromised dependency release could execute code during installation or when imported by the send script. Such code would inherit the privileges of the user running npm or Node.js and could access the Skill runtime, readable local files, environment data, and the browser debugging endpoint. The affected scope inclu ...[truncated 164 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
For detectable cases, `scripts/send_via_cdp.js` should fail before opening Gmail and print a limitation result instead of pretending the upload might work.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
For detectable cases, `scripts/send_via_cdp.js` should fail before opening Gmail and print a limitation result instead of pretending the upload might work.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill describes and instructs execution of local commands, use of Node/npm, access to a local Chrome DevTools endpoint, and handling of local file paths, but it declares no explicit tool scope or permissions boundary. That creates an authorization gap: an agent may be able to use environment/code capabilities broader than reviewers or operators expect, increasing the chance of unintended local command execution or access to sensitive local resources during email sending workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file documents a successful email send and an operational change to use Google Drive share links, both of which can affect user data privacy and external sharing. The text records the behavior as a receipt but does not include any user-facing warning about transmitting file contents or exposing access via shared links.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code creates a runtime directory, initializes a new npm project, and installs a package, which modifies the local filesystem and fetches code from the network. The script provides no confirmation prompt or user-facing disclosure before these safety-relevant operations occur.

Content

No source excerpt is available for this finding.