2

I need your opinions on this code for implementing a anti-spam solution:

  • When page/form is generated, a random string is created, eg. like $string = md5($_SERVER['REMOTE_ADDR'])
  • this string is inserted in the database, and set to expire after let's say 2 hours so we don't fill up database
  • On page load, the form has a hidden input field with no value, let's name it spam_check
  • 10, 15 or 20 secs after the page has loaded a AJAX request automatically fires off that attempts to retrieve that $string from the db & fill out spam_check input value with it.
  • when the form is submitted, we perform a simple check between the $string from the db and $_POST['spam_check'], if they don't match the message is spam...

Is this a good idea? How secure is it? The obvious advantage is that it doesn't require any action from the visitor, like reading a captcha etc.

Alex
  • 66,732
  • 177
  • 439
  • 641
  • 1
    I'm confused, even if it is spam, that value will be correct since spam tools get the html code and make posts according to that. Did I get you wrong? – Pabuc Dec 17 '10 at 12:08
  • well the idea is that a spam bot doesn't do javascript, and if it does it won't wait 10 seconds before submitting the form :) – Alex Dec 17 '10 at 12:09
  • you would have issues if the user could type very fast though – robjmills Dec 17 '10 at 12:36
  • 1
    The thing to remember is, how exposed do you plan on your form being. If for example its a contact form for a small/medium company, it is unlikely someone is going to visit your site and look at how YOUR custom code works and take the time to create/modify a bot which will wait for the ajax to return the string. Thus it would probably work fine. If this is going to be a large website with lots of exsposure then it is more likely someone may visit to work out whats going on. Of course if the code is private its harder still for them to find out whats happening. – Scoobler Dec 17 '10 at 12:59
  • I don't see why, when writing a bot, you wouldn't just write a duplicate of the AJAX request, eliminating the time wait, and given the static nature of the token at place, you would only have to retrieve it once, and then go nuts spamming. – cyber-guard Dec 17 '10 at 15:38

3 Answers3

4

Since that $string isn't very random, and the AJAX request will be visible to someone trying to circumvent your protection, it's easy to build an automation that retrieves $string beforehand and then fires off a gazillion of spam messages onto that form.

Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
3

One approach that I like a lot is to use CSS to hide a <input type="text"> element. A bot wouldn't know if it's hidden or not and a regular user will never see it.

Take a look at this post where this topic is already extensively discussed Practical non-image based CAPTCHA approaches?

Anyways, considering your real question is this a good idea?, I can't think of a reason why it wouldn't work... I think the database part isn't necessary though, there are other ways as you can see at the previous link...

Community
  • 1
  • 1
acm
  • 6,541
  • 3
  • 39
  • 44
0

Interesting. I'd be wary of thinking of it as a solution to spam / replacement for capcha, but it does make the spammers life more difficult.

However you should plan for dealing with cases where javascript is disabled (and potentially CSS too) - e.g. by assigning a div for the form, but leaving it with a default message, then writing the form into it using javascript (inline rather than waiting for onload/pageready).

$string = md5($_SERVER['REMOTE_ADDR'])

This is not a random value - and it won't change. Consider:

$string = sha1($_SERVER['REMOTE_ADDR'].rand(1000).time());

(sha1 is slightly faster than md5 despite the underlying algorithm requiring more ops).

It might be a good idea to use a session, and:

$_SERVER['string'] = sha1(session_id().rand(1000).time());

symcbean
  • 47,736
  • 6
  • 59
  • 94
  • thank you. I don't know much about sessions, I heard they are evil so I didn't search for more info :) but I'll do now – Alex Dec 17 '10 at 16:09