Skip to content

Unauthenticated SES mail still triggers ingestion Lambda + DB connection (resource exhaustion path) #826

Description

@m75gyqbsrw-boop

Summary

The SES processing chain invokes ingestion for incoming mail even when verification fails, creating a low-cost resource exhaustion path (Lambda invocations + DB connection churn) from unauthenticated email traffic.

Evidence

1) Receipt rule action chain is non-blocking for filter

cdk/lib/newswires.ts receipt rule:

  • Actions include:
    1. new Lambda({ function: emailFilterLambda, invocationType: LambdaInvocationType.EVENT })
    2. new S3({ bucket: emailBucket, ... })
    3. new Lambda({ function: ingestionLambda, invocationType: LambdaInvocationType.EVENT })

Because the filter lambda is EVENT (async), it cannot block subsequent actions.

2) Filter lambda is observational only

email-filter-lambda/src/handler.ts:

  • Calls findVerificationFailures(...).
  • On failure, logs and continues; no mechanism to stop SES pipeline actions.

3) Ingestion does expensive setup before failing email verification

ingestion-lambda/src/handler.ts:

  • main calls initialiseDbConnection() before per-record verification.
  • For SES records, processSESRecord may fail verification and return failure, but DB connection has already been created and Lambda invocation already consumed.

Impact

  • Any sender reaching this SES recipient can force ingestion-lambda invocations, DB connection initialization attempts, and log churn even when messages are rejected by verification.
  • Enables cost/availability degradation via unauthenticated email flood.
  • In high-volume abuse, can contribute to queue/processing delays for legitimate traffic.

Recommended fix

  1. Move verification gate earlier so unverified emails do not invoke ingestion path.
    • Options:
      • Use SES recipient/rule-level controls to pre-filter.
      • Make filter action synchronous/blocking where supported by architecture.
  2. Avoid early DB connection init in ingestion handler:
    • Initialize DB lazily only when a record has passed verification and requires DB write.
  3. Rate-limit / throttle email-triggered ingestion path and add abuse alarms.
  4. Consider separating SES ingestion from queue-based ingestion handlers to reduce shared blast radius.

Severity

Medium (availability/cost abuse; easy to trigger relative to impact).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions