[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cgiapp] RFC: CGI::Application::Plugin::CAPTCHA



Jason A. Crome wrote:
> So one of the forms on a site I'm developing is constantly spammed by 
> something like FormFucker, and as I'm getting tired of listening to  the
> gripes, I've taken time out of my development schedule to  investigate
> measures to solve the problem.
> 
> Enter CAPTCHA (thanks, hide, for turning me on to that!).  We can 
> generate an image with letters, numbers, etc. and display them on our 
> form, then ask our user to tell us what they are.  The easiest way I 
> have found to do this is using GD::SecurityImage.  With a little  work,
> we can produce an image like so:

Well, just to point out, CAPTCHA isn't perfect. It'll probably work for
now, but long term you may need to look at other options. Or maybe
GD::SecurityImage will pick up some better techniques...

http://sam.zoy.org/pwntcha/

> What an awful lot of work just to get a random string of characters  and
> an image that goes with it!  This is just asking for a plugin!
> 
> I've been toying with some ideas since last night, and what I am 
> looking for is an easier way to generate images, get the random  string,
> verify the security string, and eventually clean up the  images we
> generate.  So far, my (rough) interface looks something  like this:
> 
> use CGI::Application::Plugin::CAPTCHA;
> 
> sub setup
> {
>     my $self = shift;
> 
>     $self->captcha_config(
>         IMAGE_OPTIONS    => {
>             width   => 150,
>             height  => 40,
>             lines   => 10,
>             font    => "/Library/Fonts/Arial",
>             ptsize  => 18,
>             bgcolor => "#FFFF00",
>         },
>         CREATE_OPTIONS   => [ 'ttf', 'rect' ],
>         PARTICLE_OPTIONS => [ 300 ],
>         PATH             => "/tmp/",
>     );
> }

I'm sure you're planning it, but be sure to make most of these options
have reasonable defaults. For instance, if not given a PATH use
File::Temp, etc.

> sub runmode
> {
>     my $self = shift;
> 
>     my ($sec_string, $image_file) = $self->create_captcha();
> }

I don't think the user should have to call create_captcha() at all. It
should be a run mode that is automatically added to the using app.


> I think the above will work, but I'm not sure if I like how 
> verify_captcha() works.

This is how I would do it. In create_captcha() create a random string
(using something like Data::Random). Then create a hash of that string
using crypt() (and a random salt from Data::Random again). Use the
password as the text in the image and pass the hashed value in a cookie.

If the user then submits data, verify_captcha() should look at the field
in question, and then use crypt() again with the hashed value from the
cookie to verify that the string would indeed match.

> I still have the following things I'm not sure about how to best 
> implement:
> 
> - Image storage: I can either create the images on the filesystem, or 
> build them in a memory-based cache (which would mean the plugin needs 
> to add a runmode that returns an image only - doesn't sound like the 
> best way to me).  In any case, there needs to be a good way of  cleaning
> up old images.  Suggestions?

I wouldn't store the images at all. A good CAPTCHA should use an image
only once. That would be a waste to store. Just send the image directly
to the browser (with the cookie of course).

> - Session management: We need a good place to store the session id => 
> captcha mappings.  An in-memory cache would be good, but if we're 
> already using a session management mechanism, why not use it?   Problem
> is how do we integrate with multiple session management  mechanisms?  My
> thought, for now, would be to have an in-memory  cache, and if the
> programmer is using CAP::Session to use it instead,

I you use the method I described above you don't need to store anything.

> I leave it up to the user to determine best how to put the CAPTCHA on 
> their form.  create_captcha() will give them the ability to get the 
> random string of characters produced and the path and filename to the 
> image.

If create_captcha() simply returned the image to the browser then the
user could do something like this in their HTML

<img src="/my/app?rm=captcha">

And put it where ever they want.

> I could really use some feedback for this one - it's a much more 
> ambitious plugin than I've tried before, and I'm not sure if my  methods
> are the best way that some of this could be implemented.  It  seems as
> if this could be a pretty useful plugin if I could just get  a few more
> things hammered down.

The only issue that could be a problem with my approach would be if some
  or all browsers wouldn't accept cookies with an image. I can't imagine
why they wouldn't, but I've never tested it myself.

-- 
Michael Peters
Developer
Plus Three, LP


---------------------------------------------------------------------
Web Archive:  http://www.mail-archive.com/suppressed/
              http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: suppressed
For additional commands, e-mail: suppressed


Mail converted by mhonarc 2.6.15
This archive provided courtesy of JSW4.NET, Internet Hosting Services for Small Business.