phpBB2Refugees.com Logo
Not affiliated with or endorsed by the phpBB Group

Register •  Login 

Continue the legacy...

Welcome to all phpBB2 Refugees!Wave Smilie

This site is intended to continue support for the legacy 2.x line of the phpBB2 bulletin board package. If you are a fan of phpBB2, please, by all means register, post, and help us out by offering your suggestions. We are primarily a community and support network. Our secondary goal is to provide a phpBB2 MOD Author and Styles area.

[BETA] Email Blacklist


 
Search this topic... | Search MOD Development... | Search Box
Register or Login to Post    Index » MOD Development  Previous TopicPrint TopicNext Topic
Author Message
Dog Cow
Board Member



Joined: 18 Nov 2008

Posts: 378


flag
PostPosted: Wed Dec 10, 2008 6:33 pm 
Post subject: Email Blacklist

Email Blacklist - Beta

So, basically, if you send too many emails to large email providers such as Yahoo or Hotmails, and these emails bounce, you'll get marked as a spammer. This can happen when people sign up, but after a few years or months, their account closes.

What is does, is any email which is banned, is also blacklisted. You won't send emails to it. Think: Mass email! That's probably the #1 way to get blasted as a spammer. Since this blacklist goes in the emailer class, any other code which uses it will also get blacklist benefits, such as topic notification, and PM notification emails.

After some thought, I decided to use the ordinary phpBB ban list, since it makes sense.

Here's the code:

Code:

#
#-----[ OPEN ]------------------------------------------
#
includes/emailer.php
#
#
#-----[ FIND ]------------------------------------------
#
   var $use_smtp;

#
#
#-----[ AFTER, ADD ]------------------------------------------
#

   var $blacklist = array(); // array of blacklisted emails
   var $got_blacklist = false; // flag in case of empty blacklist

#
#
#-----[ FIND ]------------------------------------------
#
      $this->addresses['bcc'] = array();
      $this->vars = $this->msg = $this->extra_headers = '';
   }

#
#
#-----[ AFTER, ADD ]------------------------------------------
#

   // Check if an email is blacklisted. If so, returns true.
   function check_blacklist($email)
   {
      global $db;

      if ( (!isset($this->blacklist[0]) || empty($this->blacklist) ) && !$this->got_blacklist) // blacklist is empty, so fetch it.
      {
         $sql = 'SELECT ban_email FROM ' . BANLIST_TABLE;

         if (!$result = $db->sql_query($sql))
         {
            message_die(GENERAL_ERROR, 'Unable to fetch email blacklist', '', __LINE__, __FILE__, $sql);
         }

         while($row = $db->sql_fetchrow($result))
         {
            if(!empty($row['ban_email']))
            {
               $this->blacklist[] = $row['ban_email'];
            }
         }

         $this->got_blacklist = true; // set flag
      }

      // Quick check... is there an email supplied and blacklist entry?
      if (!isset($email[4]) || !isset($this->blacklist[0]))
      {
         return false; // not in blacklist, obviously
      }

      // Now, do the checking.

      if (in_array($email, $this->blacklist))
      {
         return true;
      }
      else
      {
         return false;
      }
   }
#
#-----[ FIND ]------------------------------------------
#

   // Sets an email address to send to
   function email_address($address)
   {
      $this->addresses['to'] = trim($address);
   }

   function cc($address)
   {
      $this->addresses['cc'][] = trim($address);
   }

   function bcc($address)
   {
      $this->addresses['bcc'][] = trim($address);
   }

#
#-----[ REPLACE WITH ]------------------------------------------
#

   // Sets an email address to send to
   function email_address($address)
   {
      // Check if this address in blacklist
      if (!$this->check_blacklist($address))
      {
         $this->addresses['to'] = trim($address);
      }
   }

   function cc($address)
   {
      // Check if this address in blacklist
      if (!$this->check_blacklist($address))
      {
         $this->addresses['cc'][] = trim($address);
      }
   }

   function bcc($address)
   {
      // Check if this address in blacklist
      if (!$this->check_blacklist($address))
      {
         $this->addresses['bcc'][] = trim($address);
      }
   }


That's it!

Some notes:
Efficiency. I doubt this will hold up for really huge blacklists. I made sure the query is executed and array built just once. Here's an idea I had: If you assume there are no duplicates in your list of addresses, you can take out that address if it matches, thus making the array smaller each time a blacklisted entry is found. There's no point in repeatedly scanning over it if it's already been found.
Back to top
drathbun
Board Member



Joined: 24 Jul 2008

Posts: 663
Location: Texas


flag
PostPosted: Wed Dec 10, 2008 7:05 pm 
Post subject: Re: Email Blacklist

Interesting idea! A couple of observations for you...

First, you might be able to tweak the query a bit here:
Code:
'SELECT ban_email FROM ' . BANLIST_TABLE

Instead of running a query for the entire banlist and then checking for a valid email address, you could consider adding a condition to the query, like this:
Code:
'SELECT ban_email FROM ' . BANLIST_TABLE . ' WHERE ban_email IS NOT NULL'


If you do any bans by username or IP address you'll skip them by checking to return only rows with an email address in the ban record.

Next, it doesn't seem that your code checks for wildcards in the email address. I have a bunch of entries of the format *@mail.ru for example to ban entire domains. Your check seems to be:
Code:
      if (in_array($email, $this->blacklist))
      {
         return true;
      }
      else
      {
         return false;
      }

Now that I am typing this, I see why this approach might be what you had in mind. The wildcard ban *@mail.ru prevents new users from registering with that domain. But if you have existing members with that email domain and they're behaving themselves, then they're not banned. Your code would check for specific addresses that have joined and since been banned, rather than applying wildcard filters to the entire membership database. So it may be that it's working as intended with the code you wrote.

_________________
phpBBDoctor Blog
Back to top
Dog Cow
Board Member



Joined: 18 Nov 2008

Posts: 378


flag
PostPosted: Wed Dec 10, 2008 10:26 pm 
Post subject: Re: Email Blacklist

I actually thought of both of those last night, and intentionally left them out.

1.) ban_email column is not indexed, so that would force us to add an index, or deal with a less-than-perfect query. I don't know if I want to go so far as to take such liberties with others' databases.

2.) Yes, I skip wildcards. The point here is blacklist, not ban. As you said, you can put a wildcard in and stop people from signing up with those emails or trying to use them in their profile. With a blacklist, I wanted existing, complete email addresses to be marked as bad, and thus not send mail to them.
Back to top
drathbun
Board Member



Joined: 24 Jul 2008

Posts: 663
Location: Texas


flag
PostPosted: Wed Dec 10, 2008 10:38 pm 
Post subject: Re: Email Blacklist

You're doing a full-table scan now, so an index doesn't help. And you can't index "null-ness" so using Is Not Null would eliminate an index on the field anyway. I really don't think there's a down side to the query change. You have to eliminate the rows somewhere, and it's probably more efficient to have the database do it for you.

Part of that would depend on the ratio of email to non-email bans, I guess.

_________________
phpBBDoctor Blog
Back to top
Dog Cow
Board Member



Joined: 18 Nov 2008

Posts: 378


flag
PostPosted: Wed Dec 10, 2008 10:58 pm 
Post subject: Re: Email Blacklist

drathbun wrote:
You're doing a full-table scan now, so an index doesn't help. And you can't index "null-ness" so using Is Not Null would eliminate an index on the field anyway. I really don't think there's a down side to the query change.

Thanks for the tip. But with the index, MySQL can get the results right from that, since it's a one-column request/index. But we still return all results in the table, even if they're not emails!

So in fact, if we add the index, and add the WHERE ban_email IS NOT NULL, not only do we scan (and thus, return) less rows, but we use the index as well. Seems to be more efficient, in my opinion.

That's from me testing it.
Back to top
Dog Cow
Board Member



Joined: 18 Nov 2008

Posts: 378


flag
PostPosted: Tue Dec 30, 2008 6:49 pm 
Post subject: Beware of accidental account bannings

Well, I found this out the hard way about 2 weeks ago.

In sessions.php, there is some code to check the user's email address against the ban list when starting a new session. Presumably, this is to ban all users using a wildcard email address.

Anyway, in the purposes of an email blacklist, this is catastrophic, since I want people to be able to login and change the address.

So, the solution is to comment out the code that checks the email address when starting a new session.
Back to top
Display posts from previous:   
Register or Login to Post    Index » MOD Development  Previous TopicPrint TopicNext Topic
Page 1 of 1 All times are GMT
 
Jump to:  

Index • About • FAQ • Rules • Privacy • Search •  Register •  Login 
Not affiliated with or endorsed by the phpBB Group
Powered by phpBB2 © phpBB Group
Generated in 0.0315 seconds using 15 queries. (SQL 0.0020 Parse 0.0009 Other 0.0287)
phpBB Customizations by the phpBBDoctor.com
Template Design by DeLFlo and MomentsOfLight.com Moments of Light Logo