PDA

View Full Version : [fixed] No flood check for activation code e-mail.


Paul
Thu 19th Sep '02, 3:08pm
Hi all,

In testing a permissions modification we made on our forum, we noticed that a user is able to follow the register.php?s=$session[sessionhash]&action=requestemail&email=$bbuserinfo[email] link numerous times, each time sending out an activation code. This could be used to effectively and maliciously flood someone's e-mail account.

I see two possible solutions off hand:
[list=1]
Restrict the number of activation codes sent to an e-mail address by time period (i.e. send once in a 24 hour period to a specific e-mail address)
Send activation code e-mail X times to an e-mail address regardless of time interval. Require that any additional e-mailings be made by the administrator via Admin CP. Have this be either a configuration option or a set value (I think twice should suffice).
[/list=1]

Another thought worth noting would be a link within the activation e-mail to allow the recipient to note that they have not requested the account to be created. This link should automatically prevent further e-mails to the address and mark the account in the Admin CP as requiring Administrative attention. This link would have to include some sort of hash (perhaps the activation ID?) to prevent denial of service attacks by other users crafting the link to shut down e-mail functions of another user.

I'd appreciate any comments on this as well as thoughts from the developers. While what I'm suggesting is "hackish", I feel that it's something that needs to be addressed in a standard install of vBulletin.

Many thanks,
Paul

Edit: For reference, the code in question is located in register.php:


if ($a=="act") {
// do activate account


and:


if ($HTTP_POST_VARS['action']=="emailcode") {

Paul
Thu 19th Sep '02, 3:59pm
This problem also exhibits itself in forgotten password e-mails. Perhaps examining useractivation table for existing activation id's and changing the type value?

Scott MacVicar
Thu 19th Sep '02, 4:31pm
Your right no checking is done, but it would have to be based on the person who its being sent to and not the person who is attempting to do so.

I'll move this to the bugs forums and see what i can do, most likely a new setting in the admin panel and simply basing it off the dateline column in the useractivation table.

Paul
Thu 19th Sep '02, 5:24pm
EDIT: See PPN's fix below. It's much sexier ;)

In order to avoid any potential abuse before this problem is examined by a developer, I have created the following modifications to guard against abuse. This fix will result in an error being displayed to the user should they attempt to send activation codes more than once in a 24-hour period. Ensure you backup your database and files before attempting to add this fix:

In register.php, find:

//save to DB
$DB_site->query("INSERT INTO useractivation VALUES (NULL,'$user[userid]','".time()."','$user[activationid]',0)");
}


Insert the following below:

// Hack: Flood checking for e-mail activation e-mails - Sept 19, 2002 - Paul
$useractivation=$DB_site->query_first("SELECT dateline FROM useractivation WHERE userid='$user[userid]' AND type=0");
if (time()-$useractivation['dateline']<=86400) {
eval("standarderror(\"".gettemplate("error_emailfloodcheck")."\");");
exit;
}
// End hack: Flood checking for e-mail activation e-mails


In member.php, find:
while ($user=$DB_site->fetch_array($users)) {

$username=unhtmlspecialchars($user[username]);


Insert the following below:

// Hack: Flood checking for e-mail activation e-mails - Sept 19, 2002 - Paul
$useractivation=$DB_site->query_first("SELECT dateline FROM useractivation WHERE userid='$user[userid]' AND type=1");
if (time()-$useractivation['dateline']<=86400) {
eval("standarderror(\"".gettemplate("error_emailfloodcheck")."\");");
exit;
}
// End hack: Flood checking for e-mail activation e-mails

Create a template named "error_emailfloodcheck" and insert the following:

We're sorry, but you must wait 24 hours before attempting to resend your activation codes. Please e-mail the <a href="mailto:$webmasteremail">webmaster</a> for assistance.

Save the template, both member.php and register.php and upload to your server.

Scott MacVicar
Thu 19th Sep '02, 6:43pm
very similar to what i had

$users=$DB_site->query("SELECT user.userid,usergroupid,username,email,password,ac tivationid FROM user LEFT JOIN useractivation ON (user.userid=useractivation.userid AND type=0) WHERE email='".addslashes(htmlspecialchars($email))."'");

change to

$users=$DB_site->query("SELECT user.userid,usergroupid,username,email,password,ac tivationid,dateline FROM user LEFT JOIN useractivation ON (user.userid=useractivation.userid AND type=0) WHERE email='".addslashes(htmlspecialchars($email))."'");

then

if ($user[usergroupid]==3) { // only do it if the user is in the correct usergroup

below that add

if($ourtimenow-$user['dateline'] <= $abusetimeout) {
eval("standarderror(\"".gettemplate("error_emailflood")."\");");
}

open /member.php

$users=$DB_site->query("SELECT userid,username,email FROM user WHERE email='".addslashes(htmlspecialchars($email))."'");

change that to

$users=$DB_site->query("SELECT user.userid,username,email,activationid,dateline FROM user LEFT JOIN useractivation ON (user.userid=useractivation.userid AND type=1) WHERE email='".addslashes(htmlspecialchars($email))."'");

then below

while ($user=$DB_site->fetch_array($users)) {

add

if($ourtimenow-$user['dateline'] <= $abusetimeout) {
eval("standarderror(\"".gettemplate("error_emailflood")."\");");
}

add this template

error_emailflood:
Sorry you may only email yourself once within a fixed period of time, please contact the <a href="mailto:$adminemail">admin</a>.

Run this sql query to add a setting
INSERT INTO `setting` ( `settingid` , `settinggroupid` , `title` , `varname` , `value` , `description` , `optioncode` , `displayorder` )
VALUES (
'', '11', 'Minimum time between lost password and activation code emails?', 'abusetimeout', '86400', 'The amount of time a user must wait before requesting a lost password or activation email to be sent again.', '', '2'
)

Just a prelimary code fix, may change for official version.

Paul
Thu 19th Sep '02, 6:48pm
Thanks for looking into this Scott!

Would the following be something that could either be incorporated into the next version or would it better released as a hack on vbulletin.org?

Originally posted by LoveShack
Another thought worth noting would be a link within the activation e-mail to allow the recipient to note that they have not requested the account to be created. This link should automatically prevent further e-mails to the address and mark the account in the Admin CP as requiring Administrative attention. This link would have to include some sort of hash (perhaps the activation ID?) to prevent denial of service attacks by other users crafting the link to shut down e-mail functions of another user.


We are examining the following behavior:

A link is provided in the initial registration e-mail and in the e-mail sent out when the e-mail address is changed to the effect of:

"If this is not your account, or you have not signed up... click here."

This link would have to include the activationid to prevent denial of service attacks.

Clicking on that link will set a value in the useractivation table. Perhaps using another unused type value (i.e. type=2?). The e-mail activation codes function and send password functions would then be modified to check for type=2. If found, instruct the user that they need to update their e-mail address and perhaps provide a form or a link to the user cp.

Any comments suggestions are welcome :)

Scott MacVicar
Thu 19th Sep '02, 7:11pm
a hack and maybe a possibility for vB3.1 post in the suggestions forum for vB3.

Paul
Thu 19th Sep '02, 10:24pm
Edit: Got it to work by resubmitting options through Admin CP .. apparently $abusetimeout wasn't set correctly via phpmyadmin.

Thanks again, Scott.

For those interested, I am working on a hack that will handle what I described on my last post. I'll post details on vbulletin.org when it's completed.

Scott MacVicar
Fri 20th Sep '02, 5:42am
the settings are cached in a template called options, you need to update the options after adding a setting to update this cache.

Paul
Fri 20th Sep '02, 7:03am
Thanks Scott. ;)

For those interested, I've created a hack that does what I've described above. You may find it at:

http://www.vbulletin.org/hacks/index.php?s=&action=showhack&hackid=668

Scott MacVicar
Mon 23rd Sep '02, 10:26am
A different fix was commited to cvs, we decided to use a hardcoded value of 60 seconds as most servers can handle that amount of request.

Paul
Mon 23rd Sep '02, 10:34am
60 Seconds? How does that deter e-mail flooding at all? This isn't a question necessarily about server load. A script could be created very easily that would refresh the page every minute. In an hour's time you'd get 60 e-mails. Unacceptable. I don't think the recipient would really appreciate that many e-mails, even if they were spaced apart by 1 minute intervals.