Amazon Web Services SES Spam Honeypot

By December 19, 2017 May 31st, 2019 No Comments

When AWS released Lambda, the 'serverless' movement began. It’s not well known that receiving emails with Amazon Simple Email Service (Amazon SES) can also trigger AWS Lambda functions. This actually opens up a world of possibilities around email security.

For our first example of a Lambda SES email rule, we show how to create a simple spam honeypot that saves malicious emails to Amazon Simple Storage Service (S3).

Before you can actually write the rule, you need to prepare your environment by completing the following steps:

  1. Setup SES to receive emails
  2. Figure out where you want to store the malicious emails
  3. Create the Lambda filter that will decided whether or not the email should be saved.

Setup SES to receive emails

If you don’t already use SES to receive emails you will need to first point your MX record for one of your domains to SES (be sure to double check the region). Amazon has a tutorial you can follow

Create or Designate an S3 Bucket

First, you will need to create or designate an S3 bucket and namespace that will store your spam emails. In our example, our S3 bucket is "yourbucket" and the namespace is "spam_emails/". When have our ruleset deployed all our spam messages will be stored in this bucket.

Create the AWS Lambda function

This is the function that will collect your spam messages. AWS will scan for viruses and spam, we just need our lamdba function to control the rule flow.

  1. Create a new function
    • Name: spam_trap
    • Runtime: Python 3.6
    • Role: "Create a new role from templates"
    • RoleName: email_spam_lambda
    • RoleTemplates: 'Basic Edge Lambda permissions'
  2. Configure your function
    • Set your handler to: ‘lambda_function.spam_trap_filter"
    • Copy and paste the code from the following gist to your lambda function.

def is_spam(event, context):
ses_notification = event['Records'][0]['ses']
message_id = ses_notification['mail']['messageId']
receipt = ses_notification['receipt']
print('Processing message:', message_id)
is_spam = (receipt['spamVerdict']['status'] == 'FAIL' or
receipt['virusVerdict']['status'] == 'FAIL')
if is_spam:
print('SPAM message:', message_id)
print('HAM message:', message_id)
return is_spam
def spam_filter(event, context):
'''Reject all spam emails'''
print('Starting - inbound-ses-spam-filter')
if is_spam(event, context):
return {'disposition': 'stop_rule'}
def spam_trap_filter(event, context):
'''Collect All Spam Emails'''
print('Starting - inbound-ses-spam-trap-filter')
if not is_spam(event, context):
return {'disposition': 'stop_rule'}

Create/Edit Your SES Ruleset

The SES Ruleset is what actually runs when you receive emails. If you don’t have an active ruleset, you will need to create a ruleset.

A ruleset is a group of rules you can create that perform specific actions. In our example, we have one rule with 3 actions.

Create a new rule and name it "spam_trap" and make sure spam and virus scanning is enabled.

For this rule, create three actions:

  1. Call the lamdba function created earlier "email_spam_trap", make sure "RequestResponse" is selected. If the email is spam the lambda function will let it pass, it is not spam it stop this rule continue with the rest of the rules.
  2. Store the email in the s3 bucket designated in step 2.
  3. Stop the ruleset. This means malicious emails will be dropped.

Save the rule and make the ruleset your active ruleset. Now send yourself a malicious file and you should see it in S3.

We plan on having more examples in the coming months so stay tuned.