Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-48899

Forum Digest emails rejected by spam filters (false positive)

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 2.7.2, 2.7.3, 2.7.4
    • Fix Version/s: 2.7.6
    • Component/s: Forum
    • Labels:
    • Testing Instructions:
      Hide
      1. Create a forum and discussion, selecting Mail Now
      2. Make a note of the postid
      3. Ensure that a user is subscribed to the forum
      4. Run cron
        • Confirm that the message was sent
        • Check the messageid in the received mail headers. It should not contain localhost.localdomain
      5. Modify lib/phpmailer/class.phpmailer.php and find the serverHostname() function to always return 'localhost.localdomain'
      6. Update the DB:

        UPDATE mdl_forum_posts set mailed = 0 where id = [postid]
        

      7. Run cron again
        • Confirm that the message was sent
        • Check the messageid in the received mail headers. It should not contain localhost.localdomain
      Show
      Create a forum and discussion, selecting Mail Now Make a note of the postid Ensure that a user is subscribed to the forum Run cron Confirm that the message was sent Check the messageid in the received mail headers. It should not contain localhost.localdomain Modify lib/phpmailer/class.phpmailer.php and find the serverHostname() function to always return 'localhost.localdomain' Update the DB: UPDATE mdl_forum_posts set mailed = 0 where id = [postid] Run cron again Confirm that the message was sent Check the messageid in the received mail headers. It should not contain localhost.localdomain
    • Affected Branches:
      MOODLE_27_STABLE
    • Fixed Branches:
      MOODLE_27_STABLE

      Description

      Since upgrading to Moodle 2.7.2 in November, our students are reporting that Forum Digests, when sent to email addresses on certain mail providers (GMail being the most notable), are being silently rejected as spam.

      Steps to reproduce:

      (1) using a Moodle 2.7.x account with its email set to a gmail address (or other provider with strict spam filtering), subscribe to a sufficiently busy forum.
      (2) Set Forum Digest on for that forum or set Forum Digest on globally in your profile settings.
      (3) Wait for Moodle to send out its scheduled Forum Digests.
      (4) Check for a Forum Digest email in gmail. If the Forum Digest email is in your spam folder, check its headers - you should find that the Message-ID header contains localhost.localdomain.

      Analyzing the outgoing emails, we discovered that Moodle inserts a Message-ID: header that looks like this:
      <reallylonghexadecimalnumber>@localhost.localdomain

      The use of localhost.localdomain in this header is a major spam red flag.

      Tracing the send process, I discovered that this header is built using the phpmailer class's serverHostname() method. This attempts to determine the server's host name in this order:

      (1) The object's Hostname property
      (2) $_SERVER['SERVER_NAME']
      (3) localhost.localdomain

      When sending forum digests, this method always returns localhost.localdomain.

      This is because:

      • $this->Hostname is not set (and I could find nothing in Moodle that sets it!),
      • Forum Digest being cron-powered, $_SERVER[] is also unset because the httpd (Apache in my case) is not in the picture. PHP is running standalone from cron.

      On our Moodle instances, I have worked around this temporarily by modifying phpmailer::serverHostname() to always return the domain of our mail server (e.g. mail.royalroads.ca). This lets the forum digests through Gmail and other mail services we tested.

      In lib/phpmailer/class.phpmailer.php:

          // My cheesy workaround.
          protected function serverHostname()
          {
              if (!empty($this->Hostname)) {
                  $result = $this->Hostname;
              } elseif (isset($_SERVER['SERVER_NAME'])) {
                  $result = $_SERVER['SERVER_NAME'];
              } else {
                  $result = 'localhost.localdomain';
              }        
              // Ignore above logic and always return mail.royalroads.ca
              $result = 'mail.royalroads.ca';
             
              return $result;
          }
      

      I think this could be fixed by adding another Hostname source to phpmailer::serverHostname: $CFG->wwwroot.

      (1) $this->Hostname
      (2) $_SERVER['SERVER_NAME']
      (3) parse_url($CFG->wwwroot)['host']
      (4) localhost.localdomain

      Proposed fix:

         protected function serverHostname()
          {
              if (!empty($this->Hostname)) {
                  $result = $this->Hostname;
              } elseif (isset($_SERVER['SERVER_NAME'])) {
                  $result = $_SERVER['SERVER_NAME'];
              } elseif (isset($CFG->wwwroot)) {
                  $urlinfo = parse_url($CFG->wwwroot);
                  $result = $urlinfo['host'];
              } else {
                  $result = 'localhost.localdomain';
              }
              return $result;
          }
      

        Attachments

          Activity

            People

            Assignee:
            dobedobedoh Andrew Nicols
            Reporter:
            dethme0w Gerald Albion
            Integrator:
            David Monllaó
            Tester:
            John Okely
            Participants:
            Component watchers:
            Andrew Nicols, Jun Pataleta, Michael Hawkins, Shamim Rezaie, Simey Lameze
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Fix Release Date:
              9/Mar/15