You asked whether it’s a problem for your product teams to add “send an email” to their applications by dropping in a provider’s SDK and an API key. My short answer: it’s a bigger decision than it looks. When you integrate an application directly with an email delivery service, you take on a new trust relationship, new code, new dependencies, new long-lived secrets, and often a new inbound endpoint. Each one is a way in. And because email is how your organization talks to customers, partners, and employees, a compromise rarely stays inside the app that caused it.

This memo walks through each risk vector with incidents and vulnerabilities reported since 2020, lists the responsibilities your teams accept when they integrate directly, and closes with two recommendations.

Why a password reset email is a security decision

Picture an internal tool, or a small customer-facing app with modest data and a low profile. Its threat model is limited, and nobody worries much about it. Then someone adds password reset emails, order confirmations, or a weekly digest. The app now holds:

  • An API key or SMTP password that can send mail as your domain, with the reputation and authentication (Sender Policy Framework, DomainKeys Identified Mail, and DMARC records) your organization has built up.
  • A provider account that stores your recipient lists, message history, and sending domains.
  • One or more third-party packages that build messages from user input and talk to the network.
  • Frequently, a webhook endpoint that accepts delivery, bounce, and complaint events from the internet.

None of these were in the threat model the day before. Attackers know this. Low-profile apps with email credentials are exactly what they go looking for.

Risk vector 1: The provider

Using a provider means trusting its people, its internal tools, and its own code with your data and your sending identity. Major providers have been breached, and you can’t patch their systems for them.

The pattern matters more than any single incident. Your recipient lists, subject lines, and sending reputation live in a system you don’t control. When that system is breached, your customers can receive convincing phishing from a sender they already trust.

Risk vector 2: Integration code

The code that connects your app to the provider builds messages from user-supplied data (names, addresses, subjects) and passes them to a mail library or HTTP API. Bugs here have repeatedly led to injection, data exposure, and full site takeover. Each is tracked as a CVE (Common Vulnerabilities and Exposures) entry, rated on a 10-point severity scale. WordPress email plugins, which sit on a very large number of sites, are a good illustration:

  • Post SMTP. CVE-2023-6875, rated 9.8 (critical), let unauthenticated attackers reset the plugin’s API key and read its logs, including password reset emails, which leads to site takeover. In 2025, CVE-2025-24000 let any logged-in subscriber read full email logs and intercept an administrator’s password reset, on a plugin with more than 400,000 installations.
  • Easy WP SMTP. CVE-2020-35234: a publicly listable debug log contained password reset links. It was exploited in the wild to take over administrator accounts.
  • FluentSMTP. CVE-2024-9511, rated 9.8 by Wordfence, is an unauthenticated PHP object injection, exploitable when another installed plugin or theme supplies the code an attacker needs to chain it. CVE-2026-16636 is a stored cross-site scripting flaw: a malicious recipient display name in a message ends up as script in the email log an administrator views. Wordfence tracks the full list of FluentSMTP vulnerabilities.
  • SendGrid for WordPress. CVE-2024-43965 is a SQL injection in versions through 1.4, rated 9.8 by NIST (Wordfence entry).

The same classes of bugs show up in the general-purpose mail libraries your developers reach for:

  • Nodemailer, the most common Node.js mail library: CVE-2020-7769 allowed command-line flag injection through crafted recipient addresses when using the sendmail transport, and CVE-2021-23400 allowed header injection through line breaks in addresses. In 2025, GHSA-mm7p-fcc7-pg87 showed that a specially quoted address meant for an internal domain could be delivered to an attacker’s address instead.
  • PHPMailer: CVE-2021-34551 allowed remote code execution on Windows hosts.
  • Python’s standard email module: CVE-2024-6923 allowed header injection because newlines in headers weren’t quoted when messages were serialized.

Every application that sends mail carries its own copy of this code, at its own version, patched (or not) on its own team’s schedule.

Risk vector 3: Dependencies

Email SDKs and helper packages arrive through public package registries, and attackers publish packages there that look like the real thing.

  • postmark-mcp. A package on npm (the Node.js package registry) named postmark-mcp, a Model Context Protocol server for AI assistants that Postmark did not publish, worked as advertised for 15 versions. Then, as Postmark explained, its author added a backdoor that silently BCC’d every email to an outside address. The Hacker News reported the one-line change arrived in version 1.0.16 and that the package had 1,643 downloads. Password resets, invoices, and internal memos sent through it went to the attacker.
  • nodejs-smtp. A malicious npm package impersonating Nodemailer really did send mail, so tests passed. On import, it also modified Atomic and Exodus cryptocurrency wallets on the machine to redirect transfers to the attacker.

These packages run with the full privileges of the application that installs them, on developer laptops, build servers, and production hosts. A single bad install in one team’s app exposes everything that app can reach.

Risk vector 4: Credentials

An email API key is a high-value secret: it sends mail that passes your domain’s authentication checks. Attackers have built tools specifically to harvest these keys.

  • Androxgh0st. A joint CISA and FBI advisory describes malware that exploits known vulnerabilities to pull .env files from Laravel applications, collecting credentials for Amazon Web Services (AWS), Office 365, SendGrid, and Twilio, then using them to send mail.
  • Legion and AlienFox. Both toolkits scan the internet for exposed configuration files such as /.env. Legion harvests Amazon Simple Email Service (SES), Mailgun, Twilio, Mandrill, and Mailjet credentials and brute-forces SendGrid logins. When it finds AWS keys, it creates an administrator-level Identity and Access Management (IAM) user and tests SES sending. AlienFox harvests credentials for a similar list of providers, including SendGrid, Mailgun, Sendinblue, and SparkPost.
  • Keys shipped in mobile apps. CloudSEK analyzed 600 Android apps and found half were leaking API keys for Mailgun, Mailchimp, or SendGrid. Of the valid SendGrid keys, 121 could send mail and 42 could change two-factor authentication settings.
  • Amazon SES abuse. In a May 2025 campaign, Wiz observed an attacker use leaked AWS access keys to request production SES access in every region within ten seconds, raising the account’s limit from 200 messages a day to typically 50,000, then send tax-themed phishing.
  • SendGrid account takeover. SendGrid’s own guidance for customers experiencing account takeover names the usual causes: exposed or shared API keys, Laravel apps left in debug mode, credentials shared insecurely inside a company, and outdated WordPress or cPanel integrations.

Every application that integrates directly needs its own key, stored in its own configuration, deployed to its own hosts, and rotated by its own team. Each copy is another chance for the key to end up in a repository, a log file, a debug page, or a mobile app bundle.

Risk vector 5: Webhooks

To learn about bounces, complaints, and unsubscribes, apps expose webhook endpoints that providers call over the internet. If the app doesn’t verify that a request really came from the provider, anyone can send it fake events.

  • SendPortal. CVE-2026-15192: the open-source newsletter platform’s webhook endpoints for SendGrid, Postmark, Postal, and Mailjet had no authentication. As the related GitHub issue shows, forged bounce events can mark subscribers as bounced or unsubscribed and exclude them from future mail.
  • Discourse. CVE-2026-26077: webhook endpoints for SendGrid, Mailjet, Mandrill, Postmark, and SparkPost accepted requests without a valid token when none was configured, and the Mailpace endpoint never checked a token. Attackers could inflate users’ bounce scores until the forum stopped emailing them.

A forged “this address bounced” event sounds harmless until it silently stops password resets, security alerts, or invoices from reaching a customer. Each webhook endpoint is also new, internet-facing code in an app that may never have accepted inbound traffic before.

The damage doesn’t stay in the app

What makes email different from most integrations is where a compromise lands. An attacker with your email credentials or provider account isn’t limited to the app that leaked them. They can send mail as your organization, to your customers, with your domain’s authentication intact.

The cost lands on your organization as a whole: your customers get phished, your domain’s sending reputation suffers (which can push legitimate mail from every system into spam folders), and your incident response team inherits a breach that started in an app they may not have known sent email.

What direct integration makes each team responsible for

When an application integrates directly with an email provider, the team that owns it becomes responsible for all of the following, usually without being told:

  1. Vetting the provider’s security posture and following its incident notices.
  2. Choosing, pinning, and patching SDKs and mail libraries, and spotting look-alike packages.
  3. Validating and encoding every user-supplied value that goes into an address, header, subject, or template.
  4. Storing, scoping, rotating, and revoking API keys, and keeping them out of source control, logs, client-side code, and mobile app bundles.
  5. Enforcing two-factor authentication and access controls on the provider account.
  6. Authenticating every webhook request and treating its contents as untrusted input.
  7. Monitoring sending volume and recipients for abuse, and responding when a key leaks.
  8. Protecting the email logs and message history the app or plugin keeps, which often contain password reset links.

Multiply that list by the number of applications in your portfolio that send mail. Most product teams aren’t staffed or measured to do this well, and your security team has no single place to check that it’s being done at all.

Recommendations

Option 1: Don’t send email

The most effective control is not having the capability. If email is a nice-to-have rather than a requirement, ask whether the benefit outweighs everything above. In-app notifications, a dashboard inbox, or a notification feature in a platform your organization already secures may meet the need with far less exposure. If an app doesn’t need to send mail, it shouldn’t hold credentials that can.

Option 2: Send through a security-owned relay or outbox server

If the app must send email, don’t let it talk to the provider. Instead, have the app hand the message to an internal email relay or outbox server over your internal network. That server is part of your organization’s infrastructure, owned and operated by your IT security team, and it is the only system that holds provider credentials and talks to the provider.

This is separation of concerns applied to risk: the application decides what to send, and the relay owns how it gets delivered safely. The relay becomes a single point of enforcement for email policy. It moves both the responsibility and the authority for email security from individual development teams to the team equipped to carry it:

  • Credentials. Provider keys live in one hardened place, with one rotation process. Applications hold no provider secrets, so a compromised app, a leaked .env file, or a malicious package in one team’s build can’t send mail as your organization by going around the relay.
  • Dependencies. The security team vets, pins, scans, and upgrades the provider SDK and mail libraries once, instead of trusting dozens of teams to do it on their own schedules.
  • Provider changes. Switching or adding providers, or failing over during a provider incident, happens at the relay without touching application code.
  • Webhooks. Inbound provider events terminate at the relay, which verifies signatures before anything reaches an application. Product apps no longer need internet-facing webhook endpoints.
  • Policy. The relay can enforce allowed sender addresses and domains, rate limits per application, recipient rules, and content checks, so one compromised app can’t turn into a spam cannon.
  • Observability. One place to log, alert on, and audit every message your organization sends, so unusual volume or recipients are spotted quickly.

Applications still need to authenticate to the relay, and the relay itself must be secured and monitored. But that is one well-understood internal service instead of a scattered set of internet-facing integrations, each with its own keys, packages, and endpoints.

Bottom line

Sending an email looks like a small feature. In practice, it connects an otherwise low-risk application to a third-party provider, a stack of fast-moving dependencies, a high-value secret, and often an open inbound endpoint, and a failure in any of them can reach your customers under your name. If you can avoid sending email, do. If you can’t, route it through infrastructure your security team owns, so the people accountable for the risk also have the authority to manage it.