Email attachments are not included anymore after Symfony Mailer update
woensdag 11 juni 2025 - 299 woorden, 2 min read
After I updated the Symfony Mailer contrib module to version 1.6.1, all emails attachments were missing of the emails being sent.
Since version 1.6.0
there is a new feature for access checking on attachments to improve security on what files may be included as attachments of emails being sent. As described in this changelog
Default access set by
AttachmentAccessEmailAdjuster
. Allows public files, temporary content (viaAttachment::fromData()
) and anything that the webserver allows access to using http/https.
This means that for example private files are not attached anymore to emails. As also described in the changelog:
Custom code is needed to attach any other content. Obviously this creates extra work but it avoids the attackers emailing themselves private files such as settings.php or webserver log/config.
In one of the Drupal project I maintain, there are a lot of emails being sent with attachments which are configured as private files in the Drupal private://
directory. After updating the Symfony Mailer module, all attachments were missing which caused a major issue for that project.
The snippet below is part of the solution I’ve applied in the custom code where the emails are being sent using the EmailFactory
class:
/** @var \Drupal\symfony_mailer\Email $email */
$email = $this->emailFactory->newTypedEmail($email_params['type'], $email_params['sub_type'], $email_params);
if ($email_params['attachments']) {
/** @var File $attachment */
foreach ($email_params['attachments'] as $attachment) {
/** @var \Drupal\symfony_mailer\Attachment $at */
$at = Attachment::fromPath($attachment->getFileUri(), $attachment->getFilename());
if($at->hasAccess() === false) {
// We don't have access to the attachment, so force allowed access here.
$at->setAccess(AccessResult::allowed());
}
$email->attach($at);
}
}
$email->send();
All attachments are in the $emails_params['attachments']
array. All items are processed in a loop where an Attachment
object is created. You can check the access on this object with hasAccess()
and if false is returned, we change the access with setAccess(AccessResult::allowed())
. Also mention / don’t forget the attachment object to $email
before it’s being send.
Related Drupal issues: