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

I have a CGI form validator which pretty much just makes a random image with numbers and letters that you must time in.

Uptil now I passed the value of the characters in the form HIDDEN tag, which of course isn't secure. What other options do I have?

I was looking at CGI::Session, but is creating session variables really an efficient way to do this when every time they hit the screen the values will change? I'd think cookies would cause the same problem of inefficiencies.

Then there is encryption..I would need something that comes with Perl (or easy to install on my webhost) that not only encrypts a string but can also decrypt it back into the original information so I can check it. This to me sounds like the best method. Anyone know of a nice module for this?

What are your thoughts and ideas?



"Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

sulfericacid
  • Comment on Trouble with hidden data (need options)

Replies are listed 'Best First'.
Re: Trouble with hidden data (need options)
by ikegami (Patriarch) on Sep 24, 2004 at 23:14 UTC
    Encryption would work, but hashing is sufficient, and you don't have to manage keys. See Digest::SHA1.
Re: Trouble with hidden data (need options)
by Cody Pendant (Prior) on Sep 25, 2004 at 04:33 UTC
    Surely for this you only need the graphic "word", and a unique key which will identify it in a database?

    Say your word in the graphic is "asdfgh". You create a sufficiently random string, "645jd834nf7gn36fg0jd53vbd8" as the key and set the entry in the databse for that key to "asdfgh".

    When they submit the form, you can pass the key in your hidden field, and if $database{'645jd834nf7gn36fg0jd53vbd8'} == 'asdfgh' then they've guessed correctly. You move on to the next step and delete the entry in the db.

    Or have I missed something?



    ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss')
    =~y~b-v~a-z~s; print
      Wow, Cody... That thought never crossed my mind. I guess the problem with that is, if they don't guess the right key it'll sit in the database. It'd have to be setup to delete keys over a certain age which would be a hassle but definately possible.

      Thanks for the idea!



      "Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

      sulfericacid
        Delete the key even if the guess fails.
Re: Trouble with hidden data (need options)
by kiat (Vicar) on Sep 25, 2004 at 02:52 UTC
    I'm happy with using CGI::EncryptForm.
Re: Trouble with hidden data (need options)
by TedPride (Priest) on Sep 25, 2004 at 09:22 UTC
    Create a hash of your letters based on some internal key that your scripts know. Pass the hash to your form along with the letters, and check the submitted results to see if a hash of the user submission matches the hash you sent along with the form.

    The following is a rough example of what I mean, but keep in mind that crypt only takes the first 8 letters of the seed into account, and if you want to pass more than that to the user, you'll need a better hashing method:

    $str = 'weoij234joi'; $hash = crypt($str, '345oj34i'); $hash =~ s/[^\w]//g; print "$str $hash\n"; # user enters... $userchoice = 'weoij234joi'; $hash2 = crypt($userchoice, '345oj34i'); $hash2 =~ s/[^\w]//g; if ($hash eq $hash2) { print 'Success!'; } else { print 'Fail...'; }