The Risk You Can't Afford to Ignore: AWS SES and Email Spoofing

AWS SES is used in multiple ways - automated reminders, marketing emails, security automation & alerts, etc. There’s a risk with the domain verified on SES; often overlooked. A risk that falls at the intersection of Cloud and Enterprise risk.


TL;DR:

  • AWS SES allows verifying both individual emails and domains
  • Domain verified in AWS SES means
    • Any IAM user having required permissions can spoof any email address in the domain
    • By default, emails sent are not logged
    • Spoofed emails will have 99.9+% delivery into inboxes
  • Mitigation: Apply sending authorization policy to whitelist email addresses

Email is a critical communication channel for businesses of all sizes, and AWS SES (Simple Email Service) is a popular choice for sending and receiving emails. With AWS SES, you can send millions of emails per day and scale up or down based on your needs. It allows you to send and receive emails using your email addresses and domains.

Like other “Simple” services in AWS, SES is not a simple service. There are a lot of features available and different configurations possible with the service. So you get a lot of flexibility at the cost of simplicity.

Let’s say you want to know about SES (maybe because it’s interesting?), just open its documentation. The documentation is also not so simple. It’s just a short structured book where the most essential parts are hidden in bits and pieces at multiple places. Once you start reading, you could do three things: quit reading the docs (most common), get lost in the rabbit hole of clicking different links (very common) or understand the basics of email security and how SES works (rare, might happen).

AWS SES allows verifying two types of identities: email address and domain.

Email verification involves verifying individual email addresses that you plan to send emails from. This process involves sending a verification email to the email address and clicking on a link to confirm ownership of the address. Once an email address is verified, you can send emails from it using AWS SES.

Domain verification, on the other hand, involves verifying an entire domain that you plan to send emails from. This process involves adding a few DNS records to your domain’s DNS configuration. Once the domain is verified, you can send emails from any email address that uses that domain.

Let’s do a thought experiment: With both options available, what would you consider? Just verify a few email addresses or verify an entire domain on SES.

I would say verifying individual emails would be the answer in most scenarios. I bet that you/your company sends emails from a handful of emails and doesn’t need the entire domain to be verified.

But from experience I’ve seem some customers end up verifying the entire domain - the domain which hosts their employee and group email addresses.

While the email deliverability is ensured and your marketing/product teams are happy, there’s a risk introduced in your AWS account - Email Spoofing.

Once a domain is verified on SES, anyone having SES SMTP credentials or having ses:SendEmail or ses:SendRawEmail IAM permission on the domain resource can send email from any email address.

I mean any email address - [email protected], [email protected], [email protected], etc.

Because AWS is acting as your domain’s email server, any emails an attacker sends (phishing, foul language, NSFW, etc) have a 99.9+% chance of getting delivered to the recipient’s inbox. They will look legitimate even though the content might seem fishy.

There’s a default feature that adds fuel to this fire.

By default, emails sent using SES do not get logged anywhere (no Cloudtrail, no default logging, etc). Logging in itself is not optional for using the functionality. One could verify the domain and send a thousand emails successfully without setting up any kind of logging.


No logs, no evidence
No logs, no evidence

In case you want to log the emails sent using SES for long-term/audit purposes, you must add extra effort to set up SNS notifications and then probably route it to S3 bucket for logs using a handful of Amazon’s “Simple” services.

This vulnerability feature introduces a risk that falls at the intersection of Cloud and Enterprise risk.

As AWS SES is not under the scope of most popular Cloud Security Benchmarks (CIS, etc), I’ve not seen this issue highlighted anywhere. (Please let me know if you have read about this anywhere/in any checklist before)

In terms of Cloud Security Governance, this issue can fall under both CSPM and CIEM issues. CSPM because logging is missing for the verified domain in SES; CIEM because IAM entities can impersonate any email user in the verified domain.

Use individually verified email identites in Amazon SES wherever possible.

If you need to have a verified domain, AWS offers a way to remediate this issue and it’s hidden towards the middle of the documentation. The solution is to apply a Sending Authorization policy on the verified domain.

The authorization policy would look as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy",
    "Statement": [
        {
            "Sid": "AuthorizeFromAddress",
            "Effect": "Deny",
            "Principal": {
                "AWS": "111111111111"
            },
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn:aws:ses:us-east-1:111111111111:identity/yourdomain.com",
            "Condition": {
                "StringNotLike": {
                    "ses:FromAddress": [
                        "[email protected]",
                        "support+*@yourdomain.com",
                        "[email protected]",
                        "[email protected]"
                    ]
                }
            }
        }
    ]
}

Note: If you are using this policy, replace yourdomain.com and AWS account ID 111111111111 with correct values.

This authorization policy denies sending emails using any email address in the verified domain except the whitelisted ones.

For the logging part, there’s no other option. You have to set up SNS notifications for emails and send the logs to S3 via Kinesis Data Firehose - spending some money along this pipeline to achieve security and visibility.

I feel this risk with AWS SES hasn’t got enough attention so far. The default configuration with verified domain isn’t secure and securing it costs some effort and money along the way.

Does this mean AWS cloud services are insecure by default, it’s an evil company looking to make money, etc?

I don’t think so.

I think AWS would mitigate this issue over time. It would be great to see if they add awareness prompts as it does while making S3 bucket public. AWS customers can consciously decide if it’s an acceptable risk or not if they are aware about the risk.


Hope you liked my blog post. Please share this blog post with others who would find this useful.

If you have any doubts, feel free to reach out on LinkedIn. Please let me if you found this SES issue as part of any checklist/blog post earlier.


EDIT 1: This is a modified version of the first version of blog post. The first version described that AWS customers are made to verify domains in SES as individual verified emails would fail the DMARC check. However, there’s an option to add Custom MAIL FROM in SES to overcome the DMARC failure. Thanks to Mohit Singh for finding the in the documentation :)