Herouth Maoz wrote:
>I have a captcha system, wherein a php-generated image generates a number and
>displays it, and the user has to respond with the same number.
>
>If he does, a sensitive operation is performed, which we want to avoid being
>performed several times in a row.
>
>We find that if the user clicks the submit button on the form several times in
>a row, it creates several connections, all of which check the number and do
>the operation. Since the page does not reload between these submissions, the
>number does not get replaced.
>
>I thought I'd unregister the number directly after I verify that it's the
>right one, so that the next connection made will not reach the sensitive
>part, because its comparison will fail.
>
>However, since the data is only saved in the session at the end, when I do the
>page_close(), this is not working. I'd like to be able to control when the
>session is saved, so that only the first connection will be able to access
>that number.
>
>Any ideas?
>
>
IF you are using PHP3-style sessions with PHPlib you might try putting
the page_close() directly after unregistering the session variable. That
will save the session almost immediately after the operation is
performed, which may reduce, but won't necessarily prevent what you
describe. If you need to manipulate the session after the page_close()
you're probably out of luck, though. I'm not sure that you can do two
page_open() and page_close() calls on a page. However, this would
probably not work with PHP4 sessions, since those are saved at the end
of page execution unless the php function session_write_close() is
called. Personally, I wouldn't recommend this approach.
Another, more foolproof method would be to create a
"lockfile"--basically just a dummy file. You'd check for that file when
the script runs, and if it isn't there yet, create it, then do your
stuff. Other instances of the script will see this lockfile, and can
exit out, so they don't get executed. Then, once the original script has
processed, have it delete the lockfile. Note that with this approach you
can use whatever you want that will be visible to other instances of the
script to do the locking: a file, a record in a database table, shared
memory... whatever works best for your situation.
A couple of caveats with the lockfile approach: if the user presses the
stop button in the browser PHP may (depending on how it's configured)
stop execution of the script, leaving the lockfile there unless
something is put into place to clean up old lockfiles. (I can't find the
configuration directive on PHP.net though... perhaps someone knows what
I'm talking about?) Also, if the user hits reload or the submit button
again, their browser will be expecting output from one of these other
instances instead of the original one, so you'll want to display an
error message of some sort with a link that will go to wherever they
were supposed to have gone. To help avoid problems you may want to
include instructions that they should click submit only once, but of
course you won't want to rely on that alone.
Hope that helps...
--
___________________________
Nathaniel Price
http://www.tesserportal.net
Webmaster
|