Vulnerability Development mailing list archives

Re: CGI insecurities


From: rfp () WIRETRIP NET (rain forest puppy)
Date: Wed, 26 Jan 2000 01:54:06 -0600


Mainly I am looking for a rule that would disable any kind of execution
by striping any unacceptable characters from strings sent to the cgi
prior to passing these values on. Is this feasible? What character set
could be considered safe? If this preprocessing step also looked at
string length, is there any room left for exploitation?

Well, this is a tough call.  The steadfast standard has been to 'remove
all the bad stuff' (metacharacters, etc).  However, this falls short in
lots of situations.  You're taking the much better approach of only
keeping the good stuff.  However, what to keep depends on what the data
is.

Let's say we wanted a phone number.  Keeping only 0-9 is pretty good--it
will result in a 10 digit number (assuming area code included, in the US),
and kind of neutralize different formatting styles ( (123)456-7890 vs.
123.456.7890 vs (123) 4567890 etc).  However, say you wanted the person's
first name?  0-9 won't cut it.  A-Z will, and you may need a -, ., and '
for various punctuation.  But let's ignore those...a-zA-Z will allow the
name 'Rfp'.  So we're good, but that's different than the phone number
0-9.  What's best to do?  Make a general function that allows 0-9a-zA-Z,
or test each one separately?

Let's get back to that.  Moving onto our form, what about a memo field for
address.  Even with 0-9a-zA-Z my address will come out like
'123AmazoniaStBrazil34234'  Woops.  We need spaces, and a little
punctuation.  And what if they are to type in a memo?  Ah well, we need a
hell of a lot more then (especially spaces, punctuation, (), !?, and maybe
even $, &).  Email addresses require @.

So, going back to the question, should we just make a massive
mother-function to remove everything but /a-zA-Z0-9.()!?@ $&/ ?  That'd be
dumb...you're allowing characters in datatypes that should allow it.  You
should use specific 'scrub' routines for each datatype.  You should
attempt to also limit your diversity of datatypes too...and obviously,
scrub functions for the same datatype can be shared.

Why so stringent?  Well, it only takes a-z/. for a reverse-transversal
attack (../../somewhere/else).  I've pulled off SQL hacks with as little
as a-z0-9=; it's quite easy if you toss a '." in there.  A pipe (|) to a
perl open() call, a & or ; to a system call, or even a - to add a
different commandline switch to a system call can be troublesome.
Wildcards can prove nasty (* and ?), ~ may take you to unexpected home
directories, <> can redirect stuff, ......etc....etc....

Keep it simple. Limit your datatype to known, accepted input.  And
for Pete's sake, scrub all user input that gets feed into system or SQL
functions!

Or evil people like Brock Tellier and Mixter will own you via your CGIs.

:)

- rain forest puppy      <----- look ma, no dots!


Current thread: