Security
Email Security Considerations
Input Sanitization
Always sanitize user-provided data before including it in emails:
// Good: Good — sanitize user input
$mail->greeting('Hello ' . esc_html($userName) . '!')
->line(esc_html($userMessage));
// Bad: Bad — raw user input in email body
$mail->greeting('Hello ' . $userName . '!')
->line($userMessage);
Header Injection Prevention
The Mailable class uses individual method calls for headers, which prevents header injection attacks. Never pass raw user input directly into header values:
// Good: Good — validate email addresses
if (is_email($userEmail)) {
$mail->replyTo($userEmail);
}
// Bad: Bad — raw user input in headers
$mail->replyTo($_POST['email']);
Attachment Path Validation
Always validate file paths before attaching:
// Good: Good — validate the path exists and is within allowed directory
$allowedDir = wp_upload_dir()['basedir'];
$realPath = realpath($filePath);
if ($realPath && str_starts_with($realPath, $allowedDir)) {
$mail->attach($realPath);
}
// Bad: Bad — user-controlled path without validation
$mail->attach($_GET['file']);
Template Security
When using PHP view templates, always escape output:
<!-- Good: Good -->
<p>Hello, <?= esc_html($name) ?></p>
<a href="<?= esc_url($link) ?>">Click here</a>
<!-- Bad: Bad -->
<p>Hello, <?= $name ?></p>
<a href="<?= $link ?>">Click here</a>
URL Validation
The built-in action button uses esc_url() to sanitize URLs. When building custom HTML, always escape URLs:
// Good: The action() method auto-escapes URLs
$mail->action('Click', $url); // esc_url() applied internally
// Good: Custom HTML — manually escape
$mail->html('<a href="' . esc_url($url) . '">Link</a>');
Reporting Vulnerabilities
See security.md for vulnerability reporting procedures.
Best Practices Summary
- Sanitize all user input with
esc_html(),esc_url(),sanitize_email() - Validate email addresses with
is_email()before using them - Validate file paths before attaching — check they exist and are within allowed directories
- Escape template output — never echo raw user data in templates
- Use SMTP — configure a WordPress SMTP plugin for secure transport (TLS/SSL)
- Keep updated — update to the latest version for security patches
- Limit recipients — validate and limit the number of recipients to prevent abuse