Happy 2006! I am trying to integrate a CAPTCH image code validation
into AlienForm. The validation process works fine when the form is
submitted from the html form on my site, but if someone calls remotely
the AlienForm script on my server by submitting an altered version of
the form, he/she can post spam on my guestbook. Can you please provide
a code snippet requiring the fields 'r_code' and 'crypt' even if
those are not part of the remote form and therefore are not submitted
(POST or GET) to the script. Below is AlienForm's ParseForm
subroutine which I have modified to include the CAPTCH validation call.
I thank you in advance.
Best regards,
Alex
sub ParseForm
{
my ($key, $prefs, $buffer);
if ($ENV{'REQUEST_METHOD'} eq 'GET')
{ @pairs = split(/&/, $ENV{'QUERY_STRING'}) }
elsif ($ENV{'REQUEST_METHOD'} eq 'POST')
{
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer)
}
else {Error('Bad or Unknown Request Method',
"The form's request method must be either 'POST' or
'GET'. Please check your HTML.")}
foreach $pair (@pairs)
{
local($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/<!--(.)*?-->//mg;
$FORM{$name} = $value;
$code = $FORM{'r_code'};
$crypt = $FORM{'crypt'};
if ($name =~ /_/ and $name !~ /^_/)
{
($prefs, $key) = split /_/, $name, 2;
if ($prefs =~ /r/i and not $value) { push
@missing_values, $key }
if ($prefs =~ /e/i and $value and
(($value =~ /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/) or
($value !~
/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/)))
{ push
@bad_emails, $key }
if ($prefs =~ /d/i and $value and $value =~ /\D/) { push
@only_digits, $key }
if ($prefs =~ /w/i and $value and $value =~ /\W/) { push
@only_words, $key }
if ($prefs =~ /s/i and $value) { $value
=~ s/^(\s)*//;
$value
=~ s/(\s)*$//;
$FORM{$name} = $value; }
}
if ($code && $crypt) {
$result = &checkCode($code,$crypt);
if ($result != 1) { Error('Incorrect or expired security code!',
"Please press back, refresh the page to get a new code
(the code that you just tried has expired), and try again. You may want
to copy your comments before refreshing the page because they will be
cleared when the page refreshes. Then paste them back on the refreshed
page."); }
}
}
}
--
PLEASE NOTE: comp.infosystems.www.authoring.cgi is a
SELF-MODERATED newsgroup. aa.net and boutell.com are
NOT the originators of the articles and are NOT responsible
for their content.
HOW TO POST to comp.infosystems.www.authoring.cgi:
http://www.thinkspot.net/ciwac/howtopost.html
The code you've posted is horrendous. I would recommend using an
alternative which makes use of modern Perl code and style. For
example, please take a look at the CGI module, found at (among others):
http://perldoc.perl.org/CGI.html
If you're looking for pre-written scripts, I sugges the NMS suite of
scripts available at http://nms-cgi.sourceforge.net/
A strict answer to your question is to add the line:
die "No r_code or crypt passed"
unless exists $FORM{r_code} and exists $FORM{crypt};
However, I think you have a serious flaw in your logic. You've already
determined that someone can call your script without using your form.
What makes you think this someone cannot simply pass r_code and crypt
parameters as well?
> Below is AlienForm's ParseForm subroutine
Using the CGI module, it is not necessary to write a ParseForm
subroutine:
use CGI qw/:standard/;
die "No r_code or crypt passed"
unless param('r_code') and param('crypt');
print "Name = ", param('name'), "<br>\n";
# etc . . .
Paul Lalli
>I am trying to integrate a CAPTCH image code validation
>into AlienForm. The validation process works fine when the form is
>submitted from the html form on my site, but if someone calls remotely
>the AlienForm script on my server by submitting an altered version of
>the form, he/she can post spam on my guestbook. Can you please provide
>a code snippet requiring the fields 'r_code' and 'crypt' even if
>those are not part of the remote form and therefore are not submitted
>(POST or GET) to the script. Below is AlienForm's ParseForm
>subroutine which I have modified to include the CAPTCH validation call.
>sub ParseForm
...
> }
Do the CAPTCHA validation after the foreach loop and make it unconditional
sub ParseForm {
...
foreach $pair (@pairs) {
...
}
$result = &checkCode($code,$crypt);
if ($result != 1) {
Error(...);
}
}
--
Erika