awohld has asked for the wisdom of the Perl Monks concerning the following question:

I have a form where I want to have someone type in a security code in a text box that they read from an image to successfully submit the form.

Do you guys know of any Perl script modules or documents that explain how to do this?

Thanks
Adam

Replies are listed 'Best First'.
Re: Stop Form Hurling
by jdtoronto (Prior) on Nov 06, 2004 at 05:03 UTC
Re: Stop Form Hurling
by tachyon (Chancellor) on Nov 06, 2004 at 06:32 UTC

    Authen::Captcha and GD::SecurityImage are two of the modules that do this. You may find code posted at Re: Authen::Captcha Segmentation Fault Under mod_perl useful. Related threads are Image Verification Program and Code to Block Scripts/Harwesters (GD based?)

    There are issues with the visually impaired that bear thinking about. Another approach (can be complementary) is to log access time and IP and limit each IP to so many accesses per minute/hour/day as applicable. Like capthchas this too has some issues, most notably with lots of users behind one proxy. You can make life very hard for screen scrapers using bot tools with creative use of redirects, small javascript widgets and cookies. These measures may cause issues with the search engines which is yet another consideration.

    cheers

    tachyon

Re: Stop Form Hurling
by davido (Cardinal) on Nov 06, 2004 at 05:06 UTC

    It's not hard to write a script that will, at random group together a set of several images, each containing a number or letter. You would just need to have, for example, 36 small image files in order to display the letters A-Z (from the English alphabet) and 0-9. A little creativity could obscure the character images with visually distinguishable 'noise', that would be adequate to thwart most web spiders. That doesn't really require a module.

    For your CGI parameter handling needs, use the CGI.pm module.

    But bear in mind that such a strategy for authentication will run amok with the Americans with Disabilities Act people, as well as essentially denying access to anyone who is sufficiently visually impared. It's like hanging a "Handicap not welcome here" sign on your storefront.


    Dave

      First, I agree fully with the part about handicap access, and I think that it should be a show stopper for any moral programmer; even one getting paid for doing such work.

      Second, stringing together images is a bad idea, because you can look at the image names and (presumably) the bot can just translate the image tags to the words. Simple obfuscation might not work. My own preference for a module to do all graphics stuff is Gimp/Perl. The Perl-Server that comes with this moves the graphics processing into a seperate process from the webserver, so you only have the glue in all the apache (or ...) processes. Note however that the locking doesn't work in all versions, so I just flock() a lockfile.


      --
      Snazzy tagline here
        I think that it should be a show stopper for any moral programmer; even one getting paid for doing such work.

        It's about as immoral as building a staircase. As long as an alternative is supplied, I don't see a moral problem.

Re: Stop Form Hurling
by emav (Pilgrim) on Nov 06, 2004 at 05:37 UTC
    Randomly generate a list of letters and numbers. For an example, have a look at http://www.icthus.net/CGI-City/tut_random2.shtml. You can modify it like this:
    @array = (0..9,a..z,A..Z); srand; foreach (1..5) { $rand = int(rand scalar(@array)); push (@selected, $rand); }
    I suppose you already have the necessary alphanumeric set of image files. Just use the @selected array to incorporate the images to your document, like this:
    for ($i; $i<5; $i++) { print "<img src='image_dir/$selected[$i].jpg' border=0>"; }
    Then make a variable out of @selected to check it once the form has been submitted:
    $check_var = "@selected";
    Pass it on to the cgi script that will do the checking and you're done.

    I hope this helps as the only thing I've been doing around here is ask questions. ;-)

      Then make a variable out of @selected to check it once the form has been submitted: ... Pass it on to the cgi script that will do the checking and you're done.

      Unfortunately, this solution is not very secure. An automated script could easily figure out what to send back by looking at the image URLs, or could simply send a different value for check_var that matches their input.

      Instead of trying to code this from scratch, take a look at the existing "Captcha" implementations.

        Yeah, I know about that. I took one more step to circumvent this security flaw.

        I randomly renamed the alphanumeric images and I keep a list of correspondences between these random names and the actual values of the letters somewhere on my site. So, actually, what a robot would see in the image URLs is various names of Greek cities (e.g. "athens", "thessaloniki", etc. -- hey! I'm Greek after all ;-).

        Then, the cgi script reverses the process and checks the password. I suppose bots are not that clever to figure out what's going on.

Re: Stop Form Hurling
by TedPride (Priest) on Nov 06, 2004 at 12:30 UTC
    If you feed the images through a secondary script, you can scramble the file names so it won't be possible to match the letters that way. A more patient script can still do bit comparisons (run through the validation process a few hundred times, collect all the images, match the images to letters, then have your script match the data instead of the file names), but this requires more time and effort than most people are willing to put out, and the remaining few will be able to screw with your site regardless of how good its security is.