Back to skill

Security audit

Email Best Practices

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent email best-practices guide, but some webhook and privacy examples are unsafe enough that users should review them before installation.

Install only if you will treat the examples as reference material, not copy-paste production code. In particular, require webhook signature verification over the raw request body before processing, schema-validate verified events, limit raw payload logging, define retention and access controls, and review consent/privacy requirements for re-engagement campaigns and IP/location details in security emails.

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

T09 · Insecure Skill Coding Practices

Error
Location
references/webhooks-events.md:26
Finding

Webhook Endpoint Processes Unauthenticated, Attacker-Controlled Events

Content
View full analysis
{ // Return 200 immediately to acknowledge receipt res.status(200).send('OK'); // Process asynchronously processWebhookAsync(req.body).catch(console.error); }); ``` ### Technical Analysis This complete endpoint example passes `req.body` directly to `processWebhookAsync` without authenticating the webhook sender or verifying the payload signature. Because the endpoint is intended to be publicly accessible, any remote client capable of reaching it can submit fabricated events. Although a later section separately demonstrates signature verification, the initial example is independently usable and unsafe if copied as written. The documented event handlers perform security-relevant business operations, including suppressing email addresses, removing recipients from lists, and modifying delivery records. Processing events before authentication violates the trust boundary between an external webhook sender and internal application logic. The endpoint also returns HTTP 200 before establishing authenticity or durably queueing the event. Consequently, invalid requests receive successful acknowledgements, while failures during asynchronous processing cannot be communicated to the legitimate provider for retry. ### Attack Path 1. An application implements the endpoint shown in the documentation. 2. The endpoint is exposed publicly so the email provider can deliver events. 3. An attacker sends a crafted POST request to `/webhooks/resend`. 4. The request body impersonates an `email.bounced`, `email.complained`, or `email.delivered` event and identifies a targeted address or message. 5. The endpoint returns HTTP 200 without validating the sender. 6. `processWebhookAsync` processes the attacker-controlled ...[truncated 934 chars]
Remediation
View remediation
{ try { const event = verifyWebhook(req.rawBody, req.headers); validateEventSchema(event); await enqueueVerifiedEvent(event); return res.status(202).send(''); } catch { return res.status(400).send('Invalid webhook'); } } ); ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/webhooks-events.md:40
Finding

Webhook Signature Verification Uses a Reserialized Body Instead of Raw Request Bytes

Content
View full analysis
{ try { const payload = webhook.verify( JSON.stringify(req.body), { 'svix-id': req.headers['svix-id'], 'svix-timestamp': req.headers['svix-timestamp'], 'svix-signature': req.headers['svix-signature'], } ); // Process verified payload } catch (err) { return res.status(400).send('Invalid signature'); } }); ``` ### Technical Analysis Webhook signatures are normally computed over the exact request payload bytes sent by the provider. This example verifies `JSON.stringify(req.body)`, which serializes an already parsed JavaScript object rather than using the original request body. JSON parsing and reserialization can change insignificant-to-JSON but signature-relevant representation details, including whitespace, character escaping, numeric representation, and formatting. The resulting string may therefore differ from the signed payload even when the event is legitimate, causing verification failures. This flaw primarily creates a reliability and availability problem. Repeated signature failures may also encourage operators to disable validation or fall back to the unauthenticated endpoint example, turning the operational failure into an authentication bypass. ### Attack Path 1. An application configures ordinary JSON body-parsing middleware before the webhook route. 2. The provider sends a legitimately signed webhook request. 3. Middleware parses the original bytes into `req.body` and discards or does not expose the raw representation. 4. The route reconstructs the payload with `JSON.stringify(req.body)`. 5. The reconstructed representation d ...[truncated 872 chars]
Remediation
View remediation
{ try { const payload = webhook.verify(req.body, { 'svix-id': req.headers['svix-id'], 'svix-timestamp': req.headers['svix-timestamp'], 'svix-signature': req.headers['svix-signature'], }); // Validate and process the verified payload. return res.status(200).send('OK'); } catch { return res.status(400).send('Invalid signature'); } } ); ``` ]]>
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest description says to use the skill for a wide range of situations such as 'building email features' and 'deciding transactional vs marketing,' which are broad and potentially overlap with many ordinary development requests. It does not provide explicit trigger phrases, exclusions, or negative examples to clarify when the skill should or should not activate.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/email-types.md (reported line 76)May include surrounding context.

md
**Transactional emails:**
- Can be sent based on legitimate interest or contract fulfillment
- Must be necessary for service delivery
- Cannot contain marketing content without consent

**Marketing emails:**
- Require explicit opt-in consent

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/email-types.md (reported line 87)May include surrounding context.

md
**Transactional emails:**
- Can be sent based on legitimate interest or contract fulfillment
- Must be necessary for service delivery
- Cannot contain marketing content without consent

**Marketing emails:**
- Require explicit opt-in consent

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The guidance recommends sending re-engagement emails to inactive subscribers based on engagement history, but it does not instruct the implementer to verify a lawful basis, prior consent scope, or jurisdiction-specific restrictions before processing behavioral data and sending additional messages. In email/compliance contexts, this omission can lead to privacy violations or unlawful marketing outreach, especially for users who are inactive because consent has lapsed or was never valid for re-engagement.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The guidance recommends including IP address and location in password reset emails without any privacy minimization warning or caveat. In a best-practices reference, this can lead implementers to expose sensitive metadata unnecessarily, increasing privacy risk, legal/compliance exposure, and the chance of disclosing approximate user location to unintended recipients of the email.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The guidance to 'store raw events for debugging' can lead implementers to persist webhook payloads that contain personal data such as email addresses, engagement events, complaint data, and identifiers without minimization, retention limits, or access controls. In an email/webhook context, this increases privacy and compliance risk under GDPR/CASL/CAN-SPAM practices and can expose sensitive behavioral data if logs or storage are later accessed or leaked.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.