Back to skill

Security audit

add-mailfully

Security checks for vulnerabilities and agentic risk

Overview

This skill adds or migrates app email through a clearly disclosed workflow with test-only checks, reversible changes, and user control over production updates.

Mailfully will process your app's outgoing email. Keep test credentials locally and review changes before enabling live sending. Opens and clicks are tracked by default, including rewritten sign-in links; disable tracking if unsuitable. Use a locked local script runner where possible. Before sharing suppression lists, confirm the support channel and an approved transfer method. CLI login stores a credential beyond this session.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (50)

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ils with `ERR_PACKAGE_PATH_NOT_EXPORTED`. Use the TypeScript `fetch` helper in `references/rest-clients.md`. If this machine's Node is older than 24, skip the C

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| None | new integration | `references/api-essentials.md`, then `references/rest-clients.md` unless the project is Node 24 or later |

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`references/rest-clients.md` (Java, C#, Elixir and others): port the TypeScript `fetch` helper,

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Node older than 24, or CommonJS (TypeScript or JavaScript):** the `fetch` helper in `references/rest-clients.md`. No package to install.

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Python, Ruby, Go, PHP:** that language's helper in `references/rest-clients.md`.

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Django or Rails:** add the adapter in `references/rest-clients.md` (a Django email backend, a

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `references/rest-clients.md`: not Node 24 or later. Helpers per language, Django and Rails adapters.

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `resend` | migration | `references/migrate-resend.md` |

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `references/migrate-resend.md`: from Resend (React Email, attachments by URL, scheduled sends).

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `@sendgrid/mail`, `sendgrid` | migration | `references/migrate-sendgrid.md` |

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`references/migrate-sendgrid.md`. It waits out `retry-after` and prefixes every `Idempotency-Key` with

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `references/migrate-sendgrid.md`: from SendGrid, and `sendEach` for any per-recipient send.

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `postmark` | migration | `references/migrate-postmark.md` |

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `references/migrate-postmark.md`: from Postmark (message streams, tracking flags, templates).

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`, Symfony `MAILER_DSN`, or Django, Rails or Laravel set to SMTP | migration | `references/migrate-nodemailer.md` (a `MAILER_DSN` naming SendGrid or Postmark us

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `references/migrate-nodemailer.md`: from Nodemailer, `smtplib` or any framework's SMTP settings.

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Read `references/webhooks.md`.

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `references/webhooks.md`: phase 5. Event names, headers, tested verifiers, the test vector.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/api-essentials.md (reported line 319)May include surrounding context.

python
import os

ENV_FILE = ".env"  # the env file the app loads


def load_mailfully_key(path=ENV_FILE):

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% 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 · SKILL.md (reported line 40)May include surrounding context.

md
Ground rules for every phase:

- Never ask the user to paste the key into the chat. Never read, print, grep or parse the env file or the key in shell.
  If a key shows up in the conversation anyway, tell the user to revoke it and create a new one.
- The user pastes secrets into the env file themselves; the one exception is the key from the browser
  sign-in in phase 2, which the CLI writes. You never write a key: the only thing you write about

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
Test mode needs no DNS and no verified domain, and it delivers to no real inbox.
4. Prints the returned `id` (`messageId` from the Nodemailer wrapper) and `status`. If the send returns
   `status: "canceled"`, or raises on it (`MailfullySendError` with `type: "canceled"` from the wrapper, or the Django or Rails adapter's error), every recipient was suppressed: say so and stop; do not report success.
5. Polls `GET https://api.mailfully.com/v1/emails/<id>` with the same key (header
   `Authorization: Bearer <key>`, read from the environment inside the script) every 5 s for up to 2
   minutes, printing `last_event` each time. It keeps polling on `queued`, `sending`, `sent`, `held`,
   `paused_hold` or `released`, stops on `delivered` (success), and stops on any other word as final and

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/migrate-postmark.md (reported line 504)May include surrounding context.

After (with send_email from the Python helper in rest-clients.md):

python
# send_email (mailfully_client.py, from rest-clients.md) POSTs to https://api.mailfully.com/v1/emails.
import logging

from mailfully_client import send_email

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/migrate-sendgrid.md (reported line 139)May include surrounding context.

After (with send_email from the Python helper in rest-clients.md):

python
# send_email (mailfully_client.py, from rest-clients.md) POSTs to https://api.mailfully.com/v1/emails.
import logging

from mailfully_client import send_email

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/migrate-sendgrid.md (reported line 343)May include surrounding context.

imports:

ts
// sendEmail (lib/mailfully.ts, from rest-clients.md) POSTs to https://api.mailfully.com/v1/emails.
import { setTimeout as sleep } from "node:timers/promises";
import { MailfullyApiError, sendEmail, type MailfullyEmail } from "./mailfully";

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/migrate-sendgrid.md (reported line 428)May include surrounding context.

python
# send_email and MailfullyError (mailfully_client.py, from rest-clients.md) POST to
# https://api.mailfully.com/v1/emails, take an idempotency key and carry a 429's retry-after seconds.
import http.client
import os
import time

Static analysis

No suspicious patterns detected.