Log in

View Full Version : Excessive Smilies overloading Servers


Kaelon
07-20-2002, 03:12 AM
One of my over-zealous (read: bored) users demonstrated an exploit / flaw in vB earlier this evening that I'd like to share with the rest of you to see if: (a) this has been solved; (b) there is a hack which corrects it; or (c) if any of you have come across the issues and have implemented a fix.

This applies to vBulletin 2.2.6, though I suspect it may apply to all previous versions as well.

Problem: When a user enters nothing but a bunch of smilies in the entire "Message:" field of a post, the server's load rises above 5.00 (much higher at times) while processing the smilies. The post is then not made, and the server executes a cold flush of the system RAM.

I've repeated this test several times, and the results seem fairly consistent. Flood a vBulletin with enough smilies and you can basically take it out of commission.

Possible Solution: Eliminate the use of smilies on the forums in question, or implement an algorithm that limits the number of smilies that a user can enter into the Message field. The question is - how exactly would one eliminate the smilies? Just remove them from the list of smilies in the vBulletin Control Panel?

Thoughts on this anyone?

Kaelon
07-21-2002, 07:33 PM
No one is concerned about this? :p

Kaelon

FWC
07-21-2002, 10:53 PM
Originally posted by Kaelon
Possible Solution: ..., or implement an algorithm that limits the number of smilies that a user can enter into the Message field.This is already built in to vB. It's in Posting code allowances in vBulletin Options in the admin cp.

Kaelon
07-22-2002, 06:15 PM
That's incorrect. The vBulletin Posting Code Allowances section only permits limiting how one inserts smilies, not how many smilies one can have in the text. What we need to correct this flaw is a setting that would limit the maximum number of smilies (and run a check before the post is processed).


Allow vB IMG code in signatures?

Allow vB code in signatures?

Allow smilies in signatures?

Allow HTML in signatures?

Maximum images per post/signature
Maximum number of images to allow in posts / signatures. Set this to 0 to have no effect.

Clickable Smilies per Row
When a user has enabled the clickable vbcode/smilies how many smilies do you want to show per row?

Clickable Smilies Total
When a user has enabled the clickable vbcode/smilies how many smilies do you want to display on the screen before the user is prompted to click for more.

Allow Dynamic URL for [img] tags?
If this is set to 'no', the [img] tag will not be displayed if the path to the image contains dynamic characters such as ? and &. This can prevent malicious use of the tag.

Allow vBcode Buttons & Clickable Smilies?
This global switch allows you to completely disable vBcode buttons and clickable smilies.

Xenon
07-22-2002, 06:24 PM
Maximum images per post/signature
Maximum number of images to allow in posts / signatures. Set this to 0 to have no effect.

this affects also smilies

FWC
07-23-2002, 05:54 AM
Originally posted by Kaelon
That's incorrect. The vBulletin Posting Code Allowances section only permits limiting how one inserts smilies, not how many smilies one can have in the text. Interesting. Then there is something wrong with your board. It does limit the number of smilies on my board and any other I've ever seen.

Kaelon
07-24-2002, 08:56 PM
Originally posted by Xenon
Maximum images per post/signature
Maximum number of images to allow in posts / signatures. Set this to 0 to have no effect.

this affects also smilies

Yep, but that doesn't solve the problem, because the smilies are still processed even before the post is rejected - taking up server resources. We need to figure out a way to pre-determine whether the number of smilies in the submitted text exceeds a certain number, before actually processing the thread and converting smilies into image links. The conversion process is surprisingly very server-intensive.

Kaelon

Xenon
07-24-2002, 09:05 PM
when you click on send posting it'll be preparsed.
newreply.php: // check max images
if ($maximages!=0) {
$parsedmessage=bbcodeparse($message,$forumid,$allo wsmilie);
if (countchar($parsedmessage,"<img")>$maximages) {
eval("standarderror(\"".gettemplate("error_toomanyimages")."\");");
exit;
}
}


as you can see in functions.php:
while ($smilie=$DB_site->fetch_array($smilies)) {
if(trim($smilie[smilietext])!="") {
$bbcode=str_replace(trim($smilie[smilietext]),"<img src=\"$smilie[smiliepath]\" border=\"0\" alt=\"\">",$bbcode);
}
}
this code runs just once for each sending process, so lets say if you have set 20 smilies this line $bbcode=str_replace(trim($smilie[smilietext]),"<img src=\"$smilie[smiliepath]\" border=\"0\" alt=\"\">",$bbcode);
is executet 20 times when someone sends a reply.
not really server intesive.

after that preparsing it counts the ammount of "<img" segments, and if its to high, the post is refused, it'll never be added to the post table so it wouldn't be added to the thread.

if your board doesn't use that behavor of checking max smilies you must have hacked it and made something wrong

Scott MacVicar
07-25-2002, 01:02 AM
I think hes talking like 1000 smilies in one post and in that case he is correct.

Kaelon
07-25-2002, 01:31 AM
Yes, that's right, PPN.

Basically, my server (which has 2 gigs of RAM, Dual P3's) doesn't even blink when a post has something like 20 or even 100 smilies. But, as I have tested personally, if you get a malicious user to come in and start spamming with a post of thousands of smilies - your server will basically come to a grinding halt.

The worst part about this, is that the post is not even processed after the server-intensive issue - so you can never figure out who it was that did this to you to take disciplinary sanctions against the abusive user.

Kaelon

Xenon
07-25-2002, 10:15 AM
hmm, but i think you cannot do anything against.

as i said before the str_replace function is executet just 20times/post
but if someone uses the same smilie 1000 times or more often it's the str_replace function which increases the server-time.
so i'd say the problem is php not vb

Sparkz
07-25-2002, 10:33 AM
I have confirmed this myself too... I basicly put 10000 bytes of smiles (ie 5000 smilies) into a new post... It loads for a while and then it just stops loading. Nothing happens...

I even tried letting PHP use up to 75MB of ram, and 120 max execution time.

Sparkz
07-25-2002, 10:45 AM
This board handled it easily, though...
https://vborg.vbsupport.ru/showthread.php?s=&threadid=41507

That post WILL most likely bog your browser down for a little while...

Scott MacVicar
07-25-2002, 11:46 AM
Yeah it took a whole 4 seconds to load :(

Logician
07-26-2002, 07:05 AM
Here is a fix for you:

edit function.php, find:

$bbcode=str_replace(trim($smilie[smilietext]),"<img src=\"$smilie[smiliepath]\" border=\"0\" alt=\"\">",$bbcode);

Before that add:


if (substr_count($bbcode, trim($smilie[smilietext]))>1000)
{
// do something bad to the spammer like automatically changing his usergroup to banned members
// notify admin about his malicious behaviour etc.
// then exit in peace.. ;-)
exit;
}


You can change 1000 with any numbers your server can handle.. This code will first count the smilie number in the post before attempting to process (replace) them and if the number is too high, it will exit and not let str_replace to run to get the server on its knees. FYI "substr_count" works VERY FAST so you dont need to worry about its performance..

BTW congratulate your "bored" members for me, it was a good catch..

Enjoy.. ;)
Logician

JJR512
07-26-2002, 09:41 AM
Using Logician's idea, here's what I used:
if (substr_count($bbcode, trim($smilie[smilietext]))>50) {
eval("standarderror(\"".gettemplate("error_toomanyimages")."\");");
exit;
}
I didn't want to automatically ban the member or anything, in case it was an honest mistake. And I only used 50, because I have a low max image setting, anyway.

Xenon
07-26-2002, 10:36 AM
normally then you should use that:
if (substr_count($bbcode, trim($smilie[smilietext]))>$maximages) {
eval("standarderror(\"".gettemplate("error_toomanyimages")."\");");
exit;
}

good idea logician :)

Kaelon
07-26-2002, 11:06 AM
Thanks, Logician!

Only problem - I tried using

if (substr_count($bbcode, trim($smilie[smilietext]))>$maximages) {
eval("standarderror(\"".gettemplate("error_toomanyimages")."\");");
exit;
}

But even if I inserted one smiley, the error_toomanyimages template would be displayed. When I hardcoded "10" instead of $maximages, everything seemed to work fine.

Thanks again, gang.

Kaelon

Xenon
07-26-2002, 11:11 AM
oh sorry that was my fault

a few lines above you find this code:
global $DB_site,$wordwrap,$allowdynimg, $bbuserinfo;

replace it withglobal $DB_site,$wordwrap,$allowdynimg, $bbuserinfo,$maximages;

Danny
07-26-2002, 07:09 PM
Originally posted by Logician
Here is a fix for you:

edit function.php, find:

$bbcode=str_replace(trim($smilie[smilietext]),"<img src=\"$smilie[smiliepath]\" border=\"0\" alt=\"\">",$bbcode);

Before that add:


if (substr_count($bbcode, trim($smilie[smilietext]))>1000)
{
// do something bad to the spammer like automatically changing his usergroup to banned members
// notify admin about his malicious behaviour etc.
// then exit in peace.. ;-)
exit;
}



where exactly am i looking for this? cause there is no function.php file only admin/functions.php and its not in that file.

i am using vb 2.2.6 btw.

Xenon
07-26-2002, 07:12 PM
yes admin/functions.php

its line 658 in a unhacked functions.php

Danny
07-26-2002, 07:27 PM
oh yeah your right so it is, sorry a find did not find it :( hmmmm.

Danny
07-26-2002, 08:57 PM
oops wrong thread

FWC
07-27-2002, 07:20 AM
Good job Logician and Xenon. :)

Rushy
12-24-2002, 09:38 PM
I really need this as we are getting spammed badly. I added the hack but it still posts the message and then You cant get into the thread it just says there was too many images inthe previous post so the thread effectively gets ruined by the spammer as noone can open it.

Is there a way to check before it actually posts the message?

Logician
12-24-2002, 09:59 PM
Originally posted by Rushy
I really need this as we are getting spammed badly. I added the hack but it still posts the message and then You cant get into the thread it just says there was too many images inthe previous post so the thread effectively gets ruined by the spammer as noone can open it.

Is there a way to check before it actually posts the message?
My code above checks the message before it is inserted into the database so it shouldnt behave like you said if you applied the code correctly and used "exit" command as I suggested.

If it's a common problem, the best practise will be changing the spammer's usergroup to banned/ moderated or restricted users inside the code to get rid of them easy and quick.

Don't forget to use "exit" command, otherwise the script will not stop and it will write the post to the database which will cause problems like you mentioned..

Xenon
12-25-2002, 09:21 PM
hmm, standarderror has included the exit since a few versions pal :)

but i have to agree, banning those users who abuse their rights is the better way :)

Rushy
12-26-2002, 11:10 AM
I tried the code above but for some reason it posts the message and then brings up the error message. If you try and then go into the thread aferwards it just syays ' you last post had too many blah blah' so I'm not sure why this is not working for us.

Originally posted by Logician

My code above checks the message before it is inserted into the database so it shouldnt behave like you said if you applied the code correctly and used "exit" command as I suggested.

If it's a common problem, the best practise will be changing the spammer's usergroup to banned/ moderated or restricted users inside the code to get rid of them easy and quick.

Don't forget to use "exit" command, otherwise the script will not stop and it will write the post to the database which will cause problems like you mentioned..

Logician
12-26-2002, 04:43 PM
Originally posted by Rushy
I tried the code above but for some reason it posts the message and then brings up the error message. If you try and then go into the thread aferwards it just syays ' you last post had too many blah blah' so I'm not sure why this is not working for us.

ok then there is one possibility left and that is your "Maximum images per post/signature" settings in Admin CP/vb settings is set to 0.

Change it to any value except 0 and the hack will work.. ;)

Boofo
12-27-2002, 12:38 AM
Glad I stumbled on to this thread. I see the geniuses are hard at work again. :)

What code would I need to warn someone with a PM telling them that they will be banned if it happens again? And can I do it for a particular user if he does it more than once?

Logician
12-27-2002, 09:05 AM
Originally posted by Boofo
What code would I need to warn someone with a PM telling them that they will be banned if it happens again?
You can play with this code:


$greeter="enter senders id";
$receiver="enter receivers id";
$title2="PM title";
eval("\$warning_pm = \"".gettemplate("warning_pm",1,0)."\";");
$DB_site->query("INSERT INTO privatemessage (privatemessageid,userid,touserid,fromuserid,title ,message,dateline,showsignature,iconid,messageread ,folderid) VALUES (NULL,$receiver,$receiver,$greeter,'".addslashes(htmlspecialchars($title2))."','".addslashes($warning_pm)."',".time().",1,1,0,0)");

However one important warning here:
bbcodeparse and bbcodeparse2 functions are called from many parts of vb code, not only when someone posts a message. Therefore if you apply a hack there you have to make sure, the conditional the hack depends will not be TRUE when the function is called from somewhere else in vb code.

Let's discuss on an example:
If you apply send PM hack above in this function and make sure it runs when a post has more than 1000 smilies, the poster who will snd a post with 1000 smilies will receive your PM. But if you don't clear all existing posts with 1000 smilies, someone who accidently visited such a post will also receive this PM because the same function will be called and the condition will prove TRUE in showthread.php too.

Bottom line is: Before applying such hacks into this function, make sure you cleared all existing posts/PMs from your database in the first place. Then you can be sure the hack will only apply to new posters only as it should..

And can I do it for a particular user if he does it more than once?
no easy way. You have to form a structure that will track warning of the users..

Boofo
12-27-2002, 09:50 AM
Thanks, Sinan. :) I'll play around with it and let you know what I come up with.

By this:

Before applying such hacks into this function, make sure you cleared all existing posts/PMs from your database in the first place.

do you mean if I have "Moderate posts" turned on? Because I don't.

Logician
12-27-2002, 10:54 AM
Originally posted by Boofo
By this:

do you mean if I have "Moderate posts" turned on? Because I don't.
No.. I mean whatever max.smilie number you specified in this hack, you make sure you don't have existing posts in your database which have that many smilies in them. If any, delete them before applying the hack.

Otherwise the hack code will apply to visitors of these threads too, not only new posters..

Boofo
12-27-2002, 11:05 AM
oh, ok, that makes a little more sense now. Thank for explaining that to me. :)

By the way, where do I set these variables?

$greeter="enter senders id";
$receiver="enter receivers id";
$title2="PM title";

Rushy
12-27-2002, 02:19 PM
I ckecked that and it's still doing it. It posts the post and then renders the thread useless.

Originally posted by Logician

ok then there is one possibility left and that is your "Maximum images per post/signature" settings in Admin CP/vb settings is set to 0.

Change it to any value except 0 and the hack will work.. ;)

eXtremeTim
06-09-2003, 03:27 PM
Hmm my windows server seems to be safe against this our at least at the moment. When i add a ton of smilies im guessing near 1000 or so then it says my script did not return a complete set of headers. But if i go to like 900 then my server just flies to the to many images page in under a second.

Kaelon
06-27-2003, 12:39 PM
Upon checking this, vBulletin 2.30 still shares this vulnerability, so I recommend that users apply this patch promptly.

Kaelon

Kaelon
09-03-2003, 01:01 AM
vBulletin 2.3.2 still, furthermore, still has this vulnerability. I would recommend it be included in vBulletin 3.

Logician
09-03-2003, 08:55 AM
Just curious: Have you ever reported it as a bug in vb.com? I think it deserves to be accepted as a "bug" so I think it would be corrected if reported in vb.com.

Tae-Hwan
10-17-2003, 08:06 PM
logician is the man!

Freddie Bingham
10-18-2003, 05:42 PM
Upon checking this, vBulletin 2.30 still shares this vulnerability, so I recommend that users apply this patch promptly.

Kaelon
I patched this in V3 http://www.vbulletin.com/forum/showthread.php?t=72331&highlight=smilies