Forum Moderators: coopster & phranque

Message Too Old, No Replies

Does "exit" not. well, exit?

         

csdude55

6:26 pm on Apr 29, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm using v5.16.3, updated in December when I moved to a new server.

I've noticed a few times that things are being submitted when they're not supposed to be, and I THOUGHT it was an anomaly. But then a few days ago I submitted something myself that threw an error (when it shouldn't have)... but continued processing, anyway.

After days and days of digging, my only theory is that "exit" doesn't stop the script anymore?

The error I'm getting is that $contents{'username'} is blank, when I know for a fact that it isn't. The form is submitted using:

<form name="calendar" action="https://www.example.com/cgi-bin/events.cgi" method="POST" enctype="multipart/form-data" onSubmit="return false">
<input type="hidden" name="event_id" value="">
<input type="hidden" name="old_flyer" value="">
<input type="hidden" name="username" value="csdude55">


Here's the relevant part of my Perl script:

#!/usr/bin/perl 

use Imager;
use File::Copy;

use Net::Whois::IP qw(whoisip_query);

# Variables
# this .lib loads 6 modules (including CGI qw(:standard) ), converts param() to %contents, connects to MySQL, and several other common scripts
# get_date() just converts localtime() to a readable $today string
require 'libs/variables.lib';
get_date();

# this .lib is used everywhere and shouldn't be an issue
eval { require 'libs/filter_profanity.lib' };

$testing = 0;
if ($today eq '20210429' && !$contents{'username'}) {
$testing = 1;

print "Content-type: text/html\n\n";
print "<pre>\n";

print "contents: u=" . $contents{'username'} . "&n=" . $contents{'name'} . "\n";
print "param: u=" . param('username') . "&n=" . param('name') . "\n";

print "</pre>";
exit;
}


The problem I'm working on is that the script thinks that $contents{'username'} is blank when it's not, so it returns an error to the user. I printed both $contents{'username'} and param('username') to make sure that the error wasn't with my conversion, and param() is blank, too, so that's not it.

But my mind is blown because the script seems to continue past this section and still writes the data to MySQL... including what I'm expecting to be in $contents{'username'}! Even though it thinks the param is blank in the earlier part of the script?

There's definitely a logic error here that's new for this version, because this script worked fine for 10 years. And another script has been letting scammers submit things that should be getting blocked by redirecting and exiting, so it appears to be writing MySQL before it redirects?

csdude55

5:25 am on Apr 30, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I narrowed the issue down to... it only happens when the user includes a picture.

When they submit the form I run a Javascript function to make sure all of the necessary fields have something in them, and the "username" field passes that. So I know it's there when they submit it, which means that, somehow, it's... lost in the Perl script? I don't know how, though. The code I posted earlier is an exact copy and paste (minus notes) so at that point it thinks that $contents{'username'} is empty. But then instead of exiting it somehow gets to line 219 to write to MySQL, and then $contents{'username'} has a value again!

For clarity, I also tried testing if ($today eq '20210429' && $contents{'username'} !~ /[A-Za-z]/) {, which is how I tested for it originally.

Also, there's nothing in the error log about it :-/

lammert

6:29 am on Apr 30, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Did you look at the maximum size/amount of input parameters through a POST/GET request your server accepts? It could be that some or all information is lost in the upload process to the server. I know where to find these settings with PHP, but have no idea with Perl.

csdude55

6:19 am on May 1, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I did... in this case the test pic is only 6kb, and as far as I can tell my limit is set to 50M.

But what doesn't make any sense at all to me is that it proceeds past the exit, and still writes to MySQL. This is the exact code to insert to MySQL:

$sth = $dbh->prepare("INSERT INTO events (username, which, category, title, location, street, city, zip, hours, admission, tele, email, website, flyer, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$sth->execute($contents{'username'}, $contents{'event_which'}, $contents{'category'}, $contents{'name'}, $contents{'location'}, $contents{'street'}, $contents{'city'}, $contents{'zip'}, $contents{'hours'}, $contents{'admission'}, $contents{'tele'}, $contents{'email'}, $contents{'website'}, $flyer, $contents{'description'}) or die $dbh->errstr;


And inexplicably, it (wrongly) thinks that $contents{'username'} is empty on line 35, but then writes the (correct) value of it on line 219.

Even weirder is that, just after the line to write to MySQL, I have a section to email the data to me. That email is never sent, so it appears to continue past the exit, write to MySQL, and then just stop for what appears to be no reason :-/

This all began when I moved to the new server. I triple checked the permissions on all directories, they're all set to 0666 and the owner/group is right.

The only new things would be the upgrade in Perl version, I installed mod_pagespeed, and I moved .htaccess to Apache configuration. I've looked through the .conf files and can't see anything that could potentially cause this, but if it's not Perl then it HAS to be there; otherwise, I'm running out of ideas