A Hidden Risk in Plain Sight: Email Spoofing in AWS SES
Amazon Simple Email Service (SES) is a reliable and scalable tool for sending transactional and marketing emails. It integrates seamlessly with the AWS ecosystem, supports standard authentication protocols like SPF, DKIM, and DMARC, and is often used in production workloads. But there’s a hidden security risk that many developers and DevOps teams overlook — email spoofing from within your own verified domain.
In this post, we’ll unpack how this issue arises in SES, the security implications, and how to lock down your configuration to prevent abuse properly.
How SES Domain Verification Works — and Where It Can Go Wrong
To use a domain with AWS SES, you must first verify ownership. This is typically done by adding DNS records — TXT for SPF and CNAME for DKIM — with your DNS provider. Once verified, SES considers that domain trusted and permits emails to be sent from any address under it.
Here’s the catch: any IAM user or role with ses:SendEmail permission can be sent from any email address within the verified domain unless you explicitly restrict it.
So, if you verify example.com, any authorized user can send mail from ceo@example.com, hr@example.com, or security@example.com, even if they have no business doing so. That’s where the risk begins.
Real-World Risks: How This Becomes a Spoofing Vector
This default behavior can create security holes in real-world environments, especially in multi-user setups or organizations with numerous microservices and IAM roles. Here’s how:
Insider Threats
A malicious or careless IAM user with broad permissions could impersonate a high-level executive or trusted internal sender to phish employees or exfiltrate data — all using your legitimate SES setup.
Leaked Credentials
If IAM access keys are accidentally committed to a GitHub repo or otherwise leaked (a common occurrence), attackers can send spoofed emails from your domain — fully authenticated by SPF/DKIM — and potentially trick your users, partners, or customers.
No Built-in Visibility
By default, SES does not store email content or expose detailed logs of what was sent and to whom. If a spoofing attack occurs, you may have limited or no visibility unless additional monitoring and logging are in place.
How to Protect Your Domain from Being Spoofed in SES
To reduce your exposure to spoofing attacks via SES, follow these best practices. Defense here is not about turning off functionality, but explicitly narrowing permissions and improving observability.
Use Granular IAM Permissions with ses:FromAddress
Always apply the principle of least privilege. Don’t give blanket ses:SendEmail access.
Instead, restrict senders to specific “From” addresses using IAM policies. For example:
{
"Effect": "Allow",
"Action": "ses:SendEmail",
"Resource": "*",
"Condition": {
"StringEquals": {
"ses:FromAddress": "noreply@example.com"
}
}
}
This policy ensures the user can send from only noreply@example.com, not from ceo@example.com or any other internal identity.
Pro tip: If you have multiple services using SES, create a separate IAM role for each, each with scoped permissions.
Enable Monitoring and Auditing
Just because SES doesn’t store email content doesn’t mean you can’t monitor activity:
Enable CloudTrail to log calls to SendEmail and SendRawEmail.
Use CloudWatch Alarms and EventBridge rules to detect unusual sending patterns.
If you need more insight, consider integrating SES with Amazon S3, Lambda, or Kinesis to inspect messages or store content for analysis.
Use Custom MAIL FROM Domains
By default, SES uses a shared MAIL FROM domain like amazonses.com, but you can configure a custom MAIL FROM domain such as bounce.example.com. This improves your email deliverability and gives you complete control over SPF alignment and bounce handling.
Set this in the SES console or via the API, and update your DNS accordingly.
Set Up and Enforce DMARC
Domain-based Message Authentication, Reporting, and Conformance (DMARC) adds another layer of protection by instructing receiving mail servers what to do when SPF or DKIM checks fail. A strong DMARC policy can prevent spoofed messages from being delivered altogether.
Example DMARC record:
v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com;
* p=reject ensures failing emails are blocked
* rua= lets you receive aggregate reports to monitor spoofing attempts
Regularly Audit IAM and SES Configurations
Periodically review IAM policies to ensure no users or roles have broader permissions than necessary.
Check for overprivileged service accounts or forgotten credentials.
Validate that your SES configurations — domains, identities, MAIL FROM settings — are still appropriate for your current architecture.
Final Thoughts
AWS SES is an excellent service for managing email at scale, but its flexibility comes with responsibility. The ability for any authorized user to spoof any email address within a verified domain is a **silent threat** that often goes unnoticed until it’s exploited.
By explicitly limiting IAM permissions, enabling logging and visibility, and enforcing modern email authentication standards, you can make SES a secure and reliable part of your stack, instead of a potential liability.
🔍 TL;DR Summary
Problem: SES allows any user with
ses:SendEmail
to send from any address in a verified domain unless restricted.Risk: Internal impersonation or external spoofing if IAM credentials are leaked.
Impact: Phishing, reputational damage, legal exposure.
Solutions:
Lock down “From” addresses using IAM conditions
Enable CloudTrail, CloudWatch, and logging
Set up custom MAIL FROM and DMARC policies
Continuously audit IAM and SES configurations
Do not assume AWS services are secure by default. Security is your responsibility — configure it wisely.