Back to skill

Security audit

Email Writer

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it advertises by automating email in the browser, but it can send mail from a live account without a required final approval step and understates where email content goes.

Review this skill carefully before installing. It is intended to operate inside logged-in email accounts, so use it only with accounts where browser automation is acceptable. Prefer draft-only use, manually review recipient, subject, account, and full body before sending, and avoid pasting untrusted HTML or attacker-provided content into messages handled by the skill.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:101
Finding

Unsanitized Email Content Is Inserted into Authenticated Mail Pages as HTML

Content
View full analysis
{ const bodyField = document.querySelector('[role="textbox"][contenteditable="true"]'); if (bodyField) { bodyField.focus(); bodyField.innerHTML = body.replace(/\n/g, '
'); } }, emailBody) ``` The equivalent Outlook implementation is: ```javascript // Fill body (Outlook) await browser.evaluate((body) => { const bodyField = document.querySelector('[aria-label="Message body"], [role="textbox"]'); if (bodyField) { bodyField.focus(); bodyField.innerHTML = body.replace(/\n/g, '
'); } }, emailBody) ``` The QQ Mail and 163 Mail implementations also write directly into iframe or editor HTML: ```javascript if (bodyField.tagName === 'IFRAME') { bodyField.contentDocument.body.innerHTML = body.replace(/\n/g, '
'); } else { bodyField.innerHTML = body.replace(/\n/g, '
'); } ``` Reply workflows repeat the same pattern: ```javascript await browser.evaluate((body) => { const bodyField = document.querySelector('[role="textbox"][contenteditable="true"]'); if (bodyField) bodyField.innerHTML = body.replace(/\n/g, '
'); }, replyBody) ``` ### Technical Analysis The skill places `emailBody` and `replyBody` into `innerHTML` without escaping or sanitizing the supplied content. Replacing newline characters with `
` does not neutralize HTML elements, event-handler attributes, forms, links, iframes, or remote resources. The sink executes inside an authenticated email-provider page. If an attacker can influence the requested email body, quoted reply material, or other content passed to these variables, crafted markup will be interpreted as HTML rather than displayed st ...[truncated 2114 chars]
Remediation
View remediation
` elements, rather than constructing HTML from the complete body. 3. If rich HTML email is an explicit requirement, process the body with a strict, well-maintained allowlist sanitizer before insertion. 4. Reject scripts, event attributes, forms, iframes, embedded objects, CSS capable of loading remote resources, and dangerous URL schemes. 5. Restrict links and media sources to validated schemes and explicitly approved destinations. 6. Apply the same safe insertion logic consistently to every Gmail, Outlook, QQ Mail, and 163 Mail compose and reply workflow. 7. Add security tests using payloads containing event attributes, remote images, forms, iframes, `javascript:` URLs, and malformed nested markup. ]]>

other

Warning
Location
SKILL.md:99
Finding

Email Workflows Perform an Irreversible Send Without Explicit Final User Approval

Content
View full analysis
{ const bodyField = document.querySelector('[role="textbox"][contenteditable="true"]'); if (bodyField) { bodyField.focus(); bodyField.innerHTML = body.replace(/\n/g, '
'); } }, emailBody) // Send (Gmail) await browser.click({ selector: '[gh="s"]' }) ``` The reply flow follows the same pattern: ```javascript await browser.click({ selector: '.zA' }) await browser.click({ selector: '[aria-label="Reply"]' }) await browser.wait({ timeout: 2000 }) await browser.evaluate((body) => { const bodyField = document.querySelector('[role="textbox"][contenteditable="true"]'); if (bodyField) bodyField.innerHTML = body.replace(/\n/g, '
'); }, replyBody) await browser.click({ selector: '[gh="s"]' }) ``` Equivalent immediate send actions are documented for other providers: ```javascript await browser.click({ selector: '[aria-label="Send"], button[title="Send"]' }) await browser.click({ selector: '.btn-send, [title="发送"], .qmBtn' }) await browser.click({ selector: '.nui-mainToolbar-sendBtn, .js-component-sendbtn' }) ``` ### Technical Analysis Sending an email is an externally visible and generally irreversible side effect. The documented workflows transition directly from populating fields to clicking Send. They do not require the agent to display the final recipient, subject, and body or obtain explicit approval immediately before transmission. The note at `SKILL.md:382` stating “Review before sending sensitive information” is advisory only. It is not integrated as a mandatory control in any co ...[truncated 1385 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:245
Finding

Broad Gmail Selector Can Reply to and Send from the Wrong Conversation

Content
View full analysis
{ const bodyField = document.querySelector('[role="textbox"][contenteditable="true"]'); if (bodyField) bodyField.innerHTML = body.replace(/\n/g, '
'); }, replyBody) await browser.click({ selector: '[gh="s"]' }) ``` ``` ### Technical Analysis The `.zA` selector broadly identifies Gmail conversation rows and does not uniquely bind the operation to a user-selected sender, subject, thread identifier, or message identifier. When multiple conversations are present, browser automation may click the first matching row or another row determined by the current DOM ordering. After opening the potentially incorrect conversation, the procedure uses another broad Reply selector and then immediately sends the generated body. There is no validation that the visible conversation, sender, reply recipient, or subject matches the user's requested target. This is a target-confusion flaw in a privileged browser workflow. Dynamic inbox ordering, asynchronous updates, new incoming mail, filtered views, or layout changes can cause the selected row to differ from the intended message. ### Attack Path 1. The authenticated Gmail inbox contains multiple rows matching `.zA`. 2. A new message, inbox refresh, sorting change, or DOM-layout change alters which matching element is selected. 3. The automation clicks `.zA` without checking the sender, subject, or stable conversation identifier. 4. The workflow opens an unintended conversation. 5. It clicks Reply, inserts `replyBody`, and immediately activates Send. 6. The reply is delivered to the recipient associated with th ...[truncated 762 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill performs send actions directly after filling fields, without a mandatory explicit pre-send confirmation from the user. In the context of browser access to a live email session, this can lead to accidental or unauthorized transmission of sensitive, incorrect, or maliciously prompted content, making the skill materially more dangerous than a draft-only tool.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The listed trigger conditions include generic phrases like "Help me write an email," "Reply to this email," and especially "Send email to someone," which overlap with common everyday requests. The description does not provide exclusion conditions or constraints clarifying when this browser-automation skill should activate versus when a simple drafting assistant would be more appropriate.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill's privacy claims are misleading: composed email content is necessarily transmitted to external email providers when sending, so saying no email content is uploaded externally and all processing is local is inaccurate. Misrepresenting data flows can cause users to expose sensitive information under false assumptions, especially in a skill that operates directly on authenticated email sessions.

Content

No source excerpt is available for this finding.

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · LICENSE.txt (reported line 12)May include surrounding context.

text
permit persons to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest limits supported providers to Gmail, Outlook, QQ Mail, and 163 Mail. The documented code additionally detects and lists 126 Mail as supported, which expands the advertised behavior beyond the stated description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.