Email Outbound Hardening

SMTP configuration and email delivery best practices

Configure ColdFusion mail services with proper authentication, encryption, rate limiting, and error handling to ensure reliable and secure email delivery.

Mail Server Configuration

You should configure mail servers in the ColdFusion Administrator following these security best practices:

  • Use a dedicated SMTP relay service instead of attempting direct delivery to recipient mail servers
  • Enable STARTTLS or SSL/TLS encryption to protect email content in transit
  • Require SMTP authentication to prevent unauthorized use of your mail server
  • Store SMTP credentials in an external secrets manager rather than in the Administrator
  • Set an appropriate connection timeout between 30-60 seconds to handle network issues gracefully

Example Configuration

SMTP Server Configuration
// In ColdFusion Administrator > Mail
Mail Server: smtp.sendgrid.net
Port: 587 (STARTTLS) or 465 (SSL)
Username: apikey
Password: <from secrets manager>
Use TLS: Yes
Verify Connection: Yes
Timeout: 60 seconds

Secure Email Sending

Send Secure Email with TLS
<cfmail
    to="#recipientEmail#"
    from="noreply@example.com"
    subject="Secure Test Message"
    type="html"
    usetls="true">
    <p>This email was sent securely over TLS</p>
</cfmail>
cfmail(
    to = recipientEmail,
    from = "noreply@example.com",
    subject = "Secure Test Message",
    type = "html",
    useTLS = true
) {
    writeOutput("<p>This email was sent securely over TLS</p>");
}

Rate Limiting

You must implement rate limiting to avoid overwhelming your SMTP provider and triggering abuse protection:

  • Configure mail spooling to queue outbound messages and send them at a controlled rate
  • Set spool interval between 15-60 seconds depending on your provider's limits
  • Track send success/failure rates and alert on anomalies
  • Implement exponential backoff for failed deliveries

Mail Spooling

Spooling separates mail generation from delivery:

  • Enable spooling in ColdFusion Administrator under Mail settings
  • Configure spool interval appropriately for your volume
  • Monitor undelivered mail directory for disk space usage
  • Implement a process to handle failed deliveries after retry attempts
Sending Spooled Email
<cfmail
    to="#recipientEmail#"
    from="noreply@example.com"
    subject="Spooled Message"
    type="html"
    spoolEnable="true">
    <p>This email will be queued and sent via the spool</p>
</cfmail>
cfmail(
    to = recipientEmail,
    from = "noreply@example.com",
    subject = "Spooled Message",
    type = "html",
    spoolEnable = true
) {
    writeOutput("<p>This email will be queued and sent via the spool</p>");
}

Error Handling

Proper error handling prevents silent failures:

Email Error Handling
<cftry>
    <cfmail
        to="#recipientEmail#"
        from="noreply@example.com"
        subject="Important Message"
        type="html"
        usetls="true">
        <p>Message content</p>
    </cfmail>

    <cfcatch type="any">
        <cflog
            file="email_errors"
            type="error"
            text="Failed to send email to #recipientEmail#: #cfcatch.message#">

        <!--- Implement retry logic or notification --->
    </cfcatch>
</cftry>
try {
    cfmail(
        to = recipientEmail,
        from = "noreply@example.com",
        subject = "Important Message",
        type = "html",
        useTLS = true
    ) {
        writeOutput("<p>Message content</p>");
    }
} catch (any e) {
    writeLog(
        file = "email_errors",
        type = "error",
        text = "Failed to send email to #recipientEmail#: #e.message#"
    );

    // Implement retry logic or notification
}

Input Validation

Always validate and sanitize email inputs to prevent header injection attacks:

Email Address Validation
<cffunction name="validateEmail" returnType="boolean">
    <cfargument name="email" type="string" required="true">

    <!--- Basic email format validation --->
    <cfif NOT isValid("email", arguments.email)>
        <cfreturn false>
    </cfif>

    <!--- Check for header injection attempts --->
    <cfif findNoCase(chr(10), arguments.email) OR findNoCase(chr(13), arguments.email)>
        <cfreturn false>
    </cfif>

    <cfreturn true>
</cffunction>

<cfif validateEmail(form.email)>
    <cfmail to="#form.email#" from="noreply@example.com" subject="Welcome">
        Thank you for signing up!
    </cfmail>
<cfelse>
    <!--- Log attempt and reject --->
    <cflog file="security" type="warning" text="Invalid email attempt: #form.email#">
</cfif>
function validateEmail(required string email) {
    // Basic email format validation
    if (!isValid("email", email)) {
        return false;
    }

    // Check for header injection attempts
    if (findNoCase(chr(10), email) || findNoCase(chr(13), email)) {
        return false;
    }

    return true;
}

if (validateEmail(form.email)) {
    cfmail(
        to = form.email,
        from = "noreply@example.com",
        subject = "Welcome"
    ) {
        writeOutput("Thank you for signing up!");
    }
} else {
    // Log attempt and reject
    writeLog(
        file = "security",
        type = "warning",
        text = "Invalid email attempt: #form.email#"
    );
}

DNS Authentication Records

Configure SPF, DKIM, and DMARC records to improve deliverability:

  • SPF (Sender Policy Framework): Identifies authorized mail servers for your domain
  • DKIM (DomainKeys Identified Mail): Cryptographically signs outbound email
  • DMARC (Domain-based Message Authentication): Specifies policy for handling failed authentication

Work with your DNS provider and SMTP relay service to configure these records properly.

Email Security Checklist

  • SMTP authentication enabled
  • STARTTLS or SSL/TLS encryption configured
  • Credentials stored in secrets manager
  • Rate limiting implemented
  • Mail spooling enabled with retry logic
  • Email addresses validated before sending
  • SPF, DKIM, DMARC records configured
  • Undelivered mail monitored
  • Send success/failure rates tracked

Gotchas

  • Port 25 blocked: Port 25 often blocked by cloud providers - use 587 or 465
  • DNS authentication: Missing SPF/DKIM records causes delivery to spam folders
  • Rate limits: Bulk sends without throttling trigger provider rate limits
  • Disk space: Unmonitored undelivered mail directory fills disk
  • Credential storage: Hard-coded SMTP credentials in code create security vulnerabilities
  • Header injection: Header injection in custom headers allows email spoofing

Need Help?

Convective can help configure secure, reliable email delivery for ColdFusion applications.

Find out more