Skip to content

sec(email): SES registration subject still built from unsanitized AccountName (PR #523 fixed only SMTP path) #544

Description

@cristim

Discovered while auditing PR #523 (which closes #401).

PR #523 wraps data.AccountName and data.Provider in sanitizeHeader() in the SMTP path (internal/email/smtp_sender.go, SendRegistrationReceivedNotification / SendPurchaseApprovalRequest subject construction). However, issue #401 explicitly identifies a second sink that the PR does not touch:

  • internal/email/templates.go (around line 808) / internal/email/sender.go SES path builds the same CUDly - New Account Registration: %s (%s) subject with the same fmt.Sprintf pattern and passes it directly to the SES API with no sanitizeHeader call.

Per issue #401, the SES path is the more dangerous of the two: sanitizeHeader is only invoked in the SMTP path, so a CR+LF in the attacker-controlled account_name (from the unauthenticated POST /api/register endpoint) reaches SES unstripped. The SMTP fix in #523 leaves this open.

Remediation

  1. Apply sanitizeHeader() to AccountName and Provider in the SES subject construction (templates.go / sender.go), mirroring the sec(email): set TLS 1.2 minimum on SMTP StartTLS and sanitize registration subject #523 SMTP fix.
  2. Add defense-in-depth at the data source: CRLF-strip and length-cap account_name in validateRegistrationRequest (internal/api/handler_registrations.go), as issue sec(email): registration notification subject built from unsanitized AccountName — SMTP header injection #401 suggested.
  3. Add a regression test on the SES subject path equivalent to TestSendRegistrationReceivedNotification_SubjectHeaderInjection.

Acceptance

  • SES subject path sanitizes AccountName and Provider before interpolation.
  • account_name CRLF-stripped and length-capped at the registration handler.
  • Regression test covers the SES path.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions