Thread: security: escaping user-supplied data

security: escaping user-supplied data

From
Jason Uhlenkott
Date:
I am writing a C program that will collect data from various untrusted
sources, and put it in a postgresql database by PQexec'ing an INSERT
INTO statement.

The statements I generate are usually of the form:
INSERT INTO foo (bar, bas) VALUES ('abc', 'def');
but the 'abc' and 'def' come from an untrusted source, so if they supply
a string like "def'); delete from foo; '" they can make me do this:
INSERT INTO foo (bar, bas) VALUES ('abc', 'def'); delete from foo; '');

What do I need to do to prevent this?  My current plan is to prepend a
backslash to every single-quote, backslash, and semicolon in the
untrusted string.  Are there any other special characters I should watch
out for?  Is it possible to do something evil despite your special
characters being prepended with a backslash?


Re: [SQL] security: escaping user-supplied data

From
Herouth Maoz
Date:
At 02:31 +0200 on 12/10/1999, Jason Uhlenkott wrote:


> The statements I generate are usually of the form:
> INSERT INTO foo (bar, bas) VALUES ('abc', 'def');
> but the 'abc' and 'def' come from an untrusted source, so if they supply
> a string like "def'); delete from foo; '" they can make me do this:
> INSERT INTO foo (bar, bas) VALUES ('abc', 'def'); delete from foo; '');
>
> What do I need to do to prevent this?  My current plan is to prepend a
> backslash to every single-quote, backslash, and semicolon in the
> untrusted string.  Are there any other special characters I should watch
> out for?  Is it possible to do something evil despite your special
> characters being prepended with a backslash?

I don't see why you would want to escape a semicolon. If you escape single
quotes and backslashes, the above situation won't happen - the string won't
be finished until the first unescaped quote - yours - is encountered.
Semicolons are not special in strings.

Herouth

--
Herouth Maoz, Internet developer.
Open University of Israel - Telem project
http://telem.openu.ac.il/~herutma




Re: [SQL] security: escaping user-supplied data

From
"Albert REINER"
Date:
On Tue, Oct 12, 1999 at 11:53:44AM +0200, Herouth Maoz wrote:
> At 02:31 +0200 on 12/10/1999, Jason Uhlenkott wrote:
> 
> 
> > The statements I generate are usually of the form:
> > INSERT INTO foo (bar, bas) VALUES ('abc', 'def');
> > but the 'abc' and 'def' come from an untrusted source, so if they supply
> > a string like "def'); delete from foo; '" they can make me do this:
> > INSERT INTO foo (bar, bas) VALUES ('abc', 'def'); delete from foo; '');
> >
> > What do I need to do to prevent this?  My current plan is to prepend a
> > backslash to every single-quote, backslash, and semicolon in the
> > untrusted string.  Are there any other special characters I should watch
> > out for?  Is it possible to do something evil despite your special
> > characters being prepended with a backslash?
> 
> I don't see why you would want to escape a semicolon. If you escape single
> quotes and backslashes, the above situation won't happen - the string won't
> be finished until the first unescaped quote - yours - is encountered.
> Semicolons are not special in strings.
> 
> Herouth

I once posted a similar question to the pgsql-novice mailing
list. There, David Rugge (1 Aug 1999) told me to escape ', ", and %,
even though I am not quite sure why you have to escape " and %. But
now that I think of it: you also need to escape \, of course, or
backslashes will either get lost or, even worse, may escape the
closing quote (think of $def="\"). Thus, using Perl and Pg, you would
do:

use Pg;
$conn = ...;

$abc="abc";
$def="def";
$conn->exec("INSERT INTO foo (bar, bas) VALUES ('" .   &stdstr($abc) . "', '" . &stdstr($def) . "')";

sub stdstr {   local $or = $_[0];   $or =~ s /\'/\\\'/g;   $or =~ s /\"/\\\"/g;   $or =~ s /%/\\%/g;   $or =~ s
/\\/\\\\/g;  return $or;
 
}

Hope that helps,

Albert.

-- 

--------------------------------------------------------------------------- Post an / Mail to / Skribu al: Albert
Reiner<areiner@tph.tuwien.ac.at>
 
---------------------------------------------------------------------------


Re: [SQL] security: escaping user-supplied data

From
Bruce Momjian
Date:
PHP has some function that auto-escapes a query string so it is safe. 
You may want to check that.


> On Tue, Oct 12, 1999 at 11:53:44AM +0200, Herouth Maoz wrote:
> > At 02:31 +0200 on 12/10/1999, Jason Uhlenkott wrote:
> > 
> > 
> > > The statements I generate are usually of the form:
> > > INSERT INTO foo (bar, bas) VALUES ('abc', 'def');
> > > but the 'abc' and 'def' come from an untrusted source, so if they supply
> > > a string like "def'); delete from foo; '" they can make me do this:
> > > INSERT INTO foo (bar, bas) VALUES ('abc', 'def'); delete from foo; '');
> > >
> > > What do I need to do to prevent this?  My current plan is to prepend a
> > > backslash to every single-quote, backslash, and semicolon in the
> > > untrusted string.  Are there any other special characters I should watch
> > > out for?  Is it possible to do something evil despite your special
> > > characters being prepended with a backslash?
> > 
> > I don't see why you would want to escape a semicolon. If you escape single
> > quotes and backslashes, the above situation won't happen - the string won't
> > be finished until the first unescaped quote - yours - is encountered.
> > Semicolons are not special in strings.
> > 
> > Herouth
> 
> I once posted a similar question to the pgsql-novice mailing
> list. There, David Rugge (1 Aug 1999) told me to escape ', ", and %,
> even though I am not quite sure why you have to escape " and %. But
> now that I think of it: you also need to escape \, of course, or
> backslashes will either get lost or, even worse, may escape the
> closing quote (think of $def="\"). Thus, using Perl and Pg, you would
> do:
> 
> use Pg;
> $conn = ...;
> 
> $abc="abc";
> $def="def";
> $conn->exec("INSERT INTO foo (bar, bas) VALUES ('" .
>     &stdstr($abc) . "', '" . &stdstr($def) . "')";
> 
> sub stdstr {
>     local $or = $_[0];
>     $or =~ s /\'/\\\'/g;
>     $or =~ s /\"/\\\"/g;
>     $or =~ s /%/\\%/g;
>     $or =~ s /\\/\\\\/g;
>     return $or;
> }
> 
> Hope that helps,
> 
> Albert.
> 
> -- 
> 
> ---------------------------------------------------------------------------
>   Post an / Mail to / Skribu al: Albert Reiner <areiner@tph.tuwien.ac.at>
> ---------------------------------------------------------------------------
> 
> ************
> 
> 


--  Bruce Momjian                        |  http://www.op.net/~candle maillist@candle.pha.pa.us            |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


Re: [SQL] security: escaping user-supplied data

From
"tjk@tksoft.com"
Date:
Here's a function in perl which should work for cleaning
a string which is sent in a query:

# The checks for already backslashed apostrophies and backslashes
# prevent tricks with these, and also allow us to run clean_text()
# several times.

sub clean_text {
   my $text = shift;
   return "" if (! defined $text || ! length($text));

   # First change backslashed backslashes back to single backslashes.
   $text =~ s/\\\\/\\/g;
   # Find backslash single quote combinations and convert them to single quotes.
   # while... is theoretically not necessary. It's there just as an assurance.
   while ($text =~ /\\\'/) {
      $text =~ s/\\\'/'/g;
   }
   # Now there should be no single quotes preceded by backslashes left.

   # Then find all backslashes and convert them to doubles.
   $text =~ s/\\/\\\\/g;
   # Now all characters preceded by a backslash should be in their
   # original state, while all backslashed single quotes are
   # just single quotes.
   # Find all single quotes and backslash them.
   # (Note: There are no single quotes preceded by a backslash, so
   # it is not possible to have a backslash which would hide a
   # backslash preceding a single quote.)
   $text =~ s/\'/\\'/g;
   return $text;
}


The function could be more efficient if you made $text a reference.
If you know how to use references in Perl, then the conversion
is easy. Just drop the "return" from the end and change all
references to $text with $$text. You should also add a check
such as "! defined $text || ! ref $text ||" to the second line's if
statement.

If you find a way to exploit this, I would like to know.

Troy



>
> At 02:31 +0200 on 12/10/1999, Jason Uhlenkott wrote:
>
>
> > The statements I generate are usually of the form:
> > INSERT INTO foo (bar, bas) VALUES ('abc', 'def');
> > but the 'abc' and 'def' come from an untrusted source, so if they supply
> > a string like "def'); delete from foo; '" they can make me do this:
> > INSERT INTO foo (bar, bas) VALUES ('abc', 'def'); delete from foo; '');
> >
> > What do I need to do to prevent this?  My current plan is to prepend a
> > backslash to every single-quote, backslash, and semicolon in the
> > untrusted string.  Are there any other special characters I should watch
> > out for?  Is it possible to do something evil despite your special
> > characters being prepended with a backslash?
>
> I don't see why you would want to escape a semicolon. If you escape single
> quotes and backslashes, the above situation won't happen - the string won't
> be finished until the first unescaped quote - yours - is encountered.
> Semicolons are not special in strings.
>
> Herouth
>
> --
> Herouth Maoz, Internet developer.
> Open University of Israel - Telem project
> http://telem.openu.ac.il/~herutma
>
>
>
> ************
>
>