PHP Verification Codes CAPTCHA
Asked Answered
J

2

8

I run a game website so I have many users logged in and they can do certain things once every two minutes.

I have a CAPTCHA system in places, and for some things it will always ask for a code, and for other things, it will ask once every 10 minutes.

I have had some players use the auto submit feature on Opera, and my CAPTCHA system does stop them.

My question is, how can I minimise the amount of times I am asking for a code, but still stop people using this auto-submit?

Jacintajacinth answered 8/4, 2010 at 12:34 Comment(2)
I think I have an idea for a non-captcha solution, but I need more details. How do they use the auto submit? What do You want to prevent them from? Submiting too quick and too often, or submiting when being away from keyboard?Honeywell
I decided to post my idea now, but You can still answerHoneywell
H
6

If I understand correctly this task doesn't require a captcha. I assume You want to see if the user did click himself, sitting in front of his PC.

new idea

Put multiple image submits on Your form:

<input type="image" name="send1" src="buttons.php?i=1" />
...
<input type="image" name="send8" src="buttons.php?i=8" />

when generating a form get a random number between 1 and 8 and save it in $_SESSION['submitnumber']. create two same size images - one empty filled with Your default background in form, the other looking like a submit button. create buttons.php that will output images with this code:

header("Content-Type: image/jpeg");
flush();
readfile($filename);

and return empty image if the $_GET[i]!=$_SESSION['submitnumber'] else return the submit image.

Accept the form if the correct imagesubmit was clicked (the browser will send You coords like send1X when user clicks the button)

It's a type of captcha, but people won't know ;)

old idea

You need two things:

1 Generate tokens for forms that are quite unique.

put <input type="hidden" name="timertoken" value="someweirdstring" /> and generate the "someweirdstring" to be a md5 hash of some (username and time)-dependant thing. I can elaborate on this, but this is a basic form token for safety and CSRF attacks blocking. The token is verified after posting.

example:

This is not a typical implementation of the token mechanism, but it will be enough.

$token=generatesomerandomtext();
$_SESSION['token']=$token; 

//... somewhere later when outputing forms:    
echo '<input type="hidden" name="token" value="'.$token.'" />';

//and when it comes back:
if($_POST['token']==$_SESSION['token']) {
   //it's ok
   }

and that's all You need. this simple example creates a unique token for every page and puts in forms. It's not time dependant and doesnt use md5, but stores the token in session. To automatically send a form that would be accepted the person has to use the form You generated or copy the token.

The real form token example would be more like this: $token=md5($username.'some secret text'.$date.$timeRoundedTo10Minutes);

//... somewhere later when outputing forms:    
echo '<input type="hidden" name="token" value="'.$token.'" />';

//and when it comes back:
if(
 ($_POST['token']==md5($username.'some secret text'.$date.$timeRoundedTo10Minutes)) ||
 ($_POST['token']==md5($username.'some secret text'.$date.$timeRoundedTo10Minutes-10minutes)) ) {
   //it's ok
   }

Why usernames? Because it removes the possibility to use one user's tokens to hack another user Why secret text (called 'salt')? Because somebody could stick together other user's name with time and do md5, but without guessing the salt he can't. Why the two comparisons? Because if now is 22:44:59 - the token is generated with 22:40 and if user sends it it's 22:45:30 so it gets rounded to 22:50 and it matches the token only if You take it back 10 minutes.

That's it for a basic example. For reference see this question.

2 Change Your submit button into <input type="image" ... as it posts the x and y coordinates of where the button was clicked. I have no idea who came up with this in specification, but it's the first time it can be used! :)

Now to see if the user clicked himself You just have to see if the coordinates are present (classic submiting won't send them) and to block simple hacking this You can also remember the last x and y in player's session and compare. It's much harder to hack it to send different coords each time.

The form tokens are there to prevent users from preparing a copy of Your form with random fields that would simulate the click coordinates. If the token changes each time it's hard to override form fields.

This is still hackable by userscript functionality, but it's much harder. And If You added a captcha once in an hour nobody would bother writing scripts that would help only for an hour and break after that (and require some effort and knowledge).

Honeywell answered 19/4, 2010 at 17:49 Comment(4)
It's better to expect that, than do nothing, isn't it? If they use keyboard, they'll see the same captcha they get now. AND if You write a line of javascript that stops submitting on enter it leaves out just lynx-alikes. They are not supported already if Hinek uses captcha, right?Honeywell
Could you write more about these tokens. I sometimes have multiple forms on one page, would this cause a problem? And do you mean generate the token and store it in my database, and add it to a form and then check them against eachother? or just store the last received token and check if they post the same token twice?Jacintajacinth
I'd recommend looking for a good article on that. It basicly works by generating a form specific string of text, sticking username and some secret ingredient into it and doing md5. It's not supposed to stay in the database. Sometimes people put it in session, but it gets complicated when there are multiple forms like in Your case. I'll put a little example of a form token for You in the answer.Honeywell
Examples should help, but I have a new idea. Wait a second ;)Honeywell
K
3

Depending on the data you receive you can gather evidents that the caller is a user. Only ask for the CAPTCHA, if the caller seems to be a bot.

Evidents can be:

  • the user agent (not reliable, because Opera can fake this)
  • the interval the submit is triggered (the more exact the call hits the i.e. every 2 minutes the more likely it is a bot)
  • if your data allows checking for returning patterns it can be an evident, too
  • ...
Kordula answered 8/4, 2010 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.