Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / lib / Drupal / Core / Mail / Plugin / Mail / PhpMail.php
index e5361492b591148f7b488c432036208e837b8fad..27e5c76e5d8977a9d2940e6f460c30c812a1077d 100644 (file)
@@ -18,6 +18,20 @@ use Drupal\Core\Site\Settings;
  */
 class PhpMail implements MailInterface {
 
+  /**
+   * The configuration factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * PhpMail constructor.
+   */
+  public function __construct() {
+    $this->configFactory = \Drupal::configFactory();
+  }
+
   /**
    * Concatenates and wraps the email body for plain-text mails.
    *
@@ -86,7 +100,10 @@ class PhpMail implements MailInterface {
       // On most non-Windows systems, the "-f" option to the sendmail command
       // is used to set the Return-Path. There is no space between -f and
       // the value of the return path.
-      $additional_headers = isset($message['Return-Path']) ? '-f' . $message['Return-Path'] : '';
+      // We validate the return path, unless it is equal to the site mail, which
+      // we assume to be safe.
+      $site_mail = $this->configFactory->get('system.site')->get('mail');
+      $additional_headers = isset($message['Return-Path']) && ($site_mail === $message['Return-Path'] || static::_isShellSafe($message['Return-Path'])) ? '-f' . $message['Return-Path'] : '';
       $mail_result = @mail(
         $message['to'],
         $mail_subject,
@@ -112,4 +129,33 @@ class PhpMail implements MailInterface {
     return $mail_result;
   }
 
+  /**
+   * Disallows potentially unsafe shell characters.
+   *
+   * Functionally similar to PHPMailer::isShellSafe() which resulted from
+   * CVE-2016-10045. Note that escapeshellarg and escapeshellcmd are inadequate
+   * for this purpose.
+   *
+   * @param string $string
+   *   The string to be validated.
+   *
+   * @return bool
+   *   True if the string is shell-safe.
+   *
+   * @see https://github.com/PHPMailer/PHPMailer/issues/924
+   * @see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.phpmailer.php#L1430
+   *
+   * @todo Rename to ::isShellSafe() and/or discuss whether this is the correct
+   *   location for this helper.
+   */
+  protected static function _isShellSafe($string) {
+    if (escapeshellcmd($string) !== $string || !in_array(escapeshellarg($string), ["'$string'", "\"$string\""])) {
+      return FALSE;
+    }
+    if (preg_match('/[^a-zA-Z0-9@_\-.]/', $string) !== 0) {
+      return FALSE;
+    }
+    return TRUE;
+  }
+
 }