Among many other problems your use of the $answer_to variable seems most dangerous. That variable is defined by whatever your users put in a form, and you use it without enough checking in 3 different ways:
- It becomes part of a hash key in your database.
- It becomes part of the value of that key.
- It becomes part of the filename used to save the message.
Aside from that the unlocked database is the most likely culprit. This (untested) code demonstrates the kind of changes you need to make:
#!/usr/bin/perl -w
use strict;
use CGI ':standard';
use Fcntl qw(:DEFAULT);
use MLDBM qw(DB_File Storable);
use MLDBM::Sync;
my $name = param('field1') || 'Anonymous';
my $email = param('field2');
my $subject = param('field3');
my $message = param('field4');
my $notify = param('notify');
my $subscribe = param('subscribe');
my $level = param('level');
my $answer_to = param('answer_to');
my $notify_checked = $notify ? 'checked' : '';
my $subscribe_checked = $subscribe ? 'checked' : '';
my @errors = ();
my $data_id;
print header;
unless ($subject) { push @errors, "You did not provide a subject." }
unless ($message) { push @errors, "$post_no_message" } # where does th
+at come from?
if (
($message =~ /(http|www|\.co|\.net|\.org| co | org |co\.)/gi ||
$subject =~ /(http|www|\.co|\.net|\.org| co | org |co\.)/gi) &&
$name !~ /^(Jiskha Webmaster|Lance|bobpursley|drwls|Ms\. Sue|Writeach
+er|PsyDAG|TchrWill)$/){
push @errors, "You are not allowed to post internet addresses."
}
if (@errors) {
print 'Message could not post because: ';
print "$_ " for @errors;
}
else {
if ($answer_to) {
$answer_to =~ s/\W//g; # UNTAINT!
$data_id = $answer_to . time()
}
else{
$data_id = time()
}
# make sure no tabs go into the tab delimited file!
$_ =~ tr/\t// for ($name,$email,$subject,$notify);
my $db = tie (my %data, 'MLDBM::Sync', 'data.db', O_CREAT|O_RDWR, 0666
+) or die "Could not tie: $!";
$data{$data_id} = "$data_id\t$name\t$email\t$subject\t$notify\t$ENV{'R
+EMOTE_ADDR'}"
or die "could not post, THIS IS A GLITCH THAT I AM TRYING TO SOLVE RIG
+HT NOW, hit refresh to try again";
undef $db;
untie %data;
open my $fh, "> data/$data_id.txt" or die "Can't open data/$data_id.tx
+t: $!";
print $fh $message;
close $fh or die "$!";
print <<OUTPUT;
post successfully posted! (you got lucky this time; but next time, by
+ seemlingly random acts, you may not get as lucky)
OUTPUT
}
1;
|