Re: troublesome inputs - Mailing list pgsql-general

From Lincoln Yeoh
Subject Re: troublesome inputs
Date
Msg-id 3.0.5.32.20010218193222.00cf9210@192.228.128.13
Whole thread Raw
In response to troublesome inputs  (Michelle Murrain <mpm@norwottuck.com>)
List pgsql-general
At 02:49 PM 2/17/01 -0500, Michelle Murrain wrote:
>in an unrecoverable error. What I need to do is two-fold - escape stuff that
>is easy (like single quotes), and do testing of types (make sure they are
not
>putting non-numerics in int fields, etc.)
>
>I'm not a newbie at either perl or pgsql, but I'm definitely not yet a guru.
>
>I've identified quotes in particualr as characters I need to make sure
>get taken care of in some way or another before I pass them to a query. Are
>there others that folks know about, especially combinations of characters
>that lead to wierdness?
>
>Other things I should be thinking about?

What you should also think about are cases where people intentionally try
to abuse your program.

Generally you filter what goes into your program so that your program can
handle it (input filtering).

Then you filter what leaves your program for another program (output
filtering).

And you have to assume that your user can send you whatever they want. For
example in a web app, if you store stuff in hidden form fields, the user
can always save the form, alter the values and submit it to you. Same goes
for storing stuff in cookies, or trying to limit options by limiting the
options shown in HTML (users can always add more options, or even do
multiple ones ;) ).

**Input filtering
For example in perl if you are using CGI what you can start with is:
$CGI::POST_MAX=$MAXBUF;

This limits the HTTP posts somewhat. HTTP GETs are usually limited by the
webserver (if it's a decent one).

Then you can do stuff like:

sub myparam {
$cgiparamname=shift;
$defaultvalue=shift;
$usermaxlength=shift||8;
$userminlength=shift||0;
$temp=param($cgiparamname);
unless (defined(temp)) {
    $temp=$defaultvalue;
}
$value=substr($temp,0,$usermaxlength);
$value=~tr/A-Za-z0-9//cd;
if ($value ne $temp) return ($value,INFO_LOSS);
if (length($value)<$userminlength) return ($value,TOO_SHORT);
return $value,OK;
}

where value is assumed to be an alphanumeric.

**Output filtering
For perl you should use the built-in DBI quoting function, or use bind vars
to stuff things into the database (after clamping down data to sane
sizes/values first).

Also, the DBI quoting feature doesn't quote %. So if you are going to use
LIKE queries and you don't want to allow users to do full table scans you
better limit how the % can appear, or just quote all occurences of % out.
Personally I prefer to support a * for wildcard, and translate the * to %
for the user with the usual sanity checks. This provides a useful layer of
abstraction.

When you are printing stuff out, make sure you quote it so that the web
browser sees it correctly - e.g. not HTML if it's not supposed to be html.
Similarly when you are printing a URL out.

**Really troublesome stuff.

I'm not sure how to quote or filter Unicode/custom encoded stuff properly.
For example if a person sends some encoded stuff, and it's fine to your
program, but when you pass it to another program, it decodes the info, and
stuff may go boom (e.g. for instance document paths suddenly look like
../../../bankdirectory/bankkeys).

I don't have any experience in dealing with this - it looks like a real
pain. Basically I've been avoiding the problem by not supporting it (I only
support known safe subsets of ASCII), but of course one day I'll have to.
Any ideas on how to do it securely are very welcome.

Cheerio,
Link.


pgsql-general by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: aliases for temp tables....
Next
From: Jean-Christophe Boggio
Date:
Subject: Re[2]: Weird indices