[ advisories | exploits | discussions | news | conventions | security tools | texts & papers ]
 main menu
- feedback
- advertising
- privacy
- FightAIDS
- newsletter
- news
- read forum
- new topic
- search

- meetings list
- recent additions
- add your info
 top 100 sites
- visit top sites
- sign up now
- members

- add your url
- add domain
- search box
- link to us

- our projects
- free email
 m4d network
- security software
- secureroot
- m4d.com
Home : Advisories : Postaci allows arbitrary SQL query execution

Title: Postaci allows arbitrary SQL query execution
Released by: Berk Demir
Date: 17th January 2001
Printable version: Click here
Popular webmail software Postaci (ships with Debian) lacks of checking

for malicious SQL code in variables coming from user while deleting

addressbook contacts, bookmarks and notes.

This gives opportunity to malicious user to execute arbitrary

SQL query.

The problem affects Postaci if using PostgreSQL as your database

backend. MySQL seems to bo not affected by this way.

PHP's mysql_query() function code does NOT allow query strings

including a semicolon inside, for passing multi queries.

The method illustrated here uses query seperating with a

semicolon, but someone can find a suitable malicious SQL code

to also exploit Postaci while using MySQL as the db backend.

The main problem is not just with Postaci, it's with the general manner

of PHP coding exercises. Both in POST and GET methods, PHP sets the

remote variable name to a global variable with the same name in the

executing PHP script (defined in the "action" field of HTML form).

If you have a    line in your HTML form;

after submission, you'll be available to reach its set value

with the variable named "$foo" in your PHP script.

Trusting the user input in this era is just the big problem.

For example :

While expecting an integer type content for $foo, user can input

a malicious string that can cause compromise of your SQL query.

Let's focus to Postaci code.

--- deletecontact.php ---

1    // security check

2    $dbq = $db->execute("select user_id from tblAdressbook where


3    $auth_user = $dbq->fields['user_id'];

4    if ($auth_user != $user_id) {

5      Header("Location: index.php?error_id=1");

6    }

7    $dbq->close();

--- deletecontact.php ---

In the relatively numbered line 1, we see a magical comment :

"// security check".

This security check is really needed but not enough unfortunately.

Lines 2,3,4,5 ensures that, anyone who is not the owner of the

contact item, can not delete it.

Up to here, everything is O.K. but the implicit trust to user input.

As seen from the code snippet, variable $item_id is never checked. It

must be an integer naturally bu as we discussed above, it's a user

input and it can be everything.

Suppose that variable "$item_id" includes the string

"144 OR TRUE; select user_id from tblAdressbook where item_id=144"

144 is a real contact item id associated with the current logged in user.

The SQL Query :

"select user_id from tblAdressbook where item_id=144 OR TRUE; \

 select user_id from tblAdressbook where item_id=144"

... will return all the user_id's also ours at the top row of the result.

At line 3, "$dbq->fields['user_id']" just points to the "user_id" column

of first row of the returned result.

      So we managed to pass the first security barrier.

Let's look at the code comes after :

--- deletecontact.php ---

8      if ($log_id == ""){

9        Header("Location: index.php?error_id=1");

10     } else {


12       $dbq = $db->execute("delete from tblAdressbook where item_id=\

13                      $item_id and user_id = $user_id");

14       $dbq->close();


16       Header("Location: adressbook.php");

17     }

--- deletecontact.php ---

At line 12, Postaci still trusts the user input and puts it into the

deleting query. Flashback to our malicious $item_id variable :

   "144 OR TRUE; select user_id from tblAdressbook where item_id=144"

Then the composed query becomes :

"delete from tblAdressbook where item_id=144 OR TRUE; select user_id \

 from tblAdressbook where item_id=144 and user_id = [your user id]"

In here. PHP code of mysql_query won't let you pass a query string

including a semicolon but this doesn't apply for Postgresql

(and maybe for MS SQL, Sybase, msql).

When we focus to the first query in the query string,

we can clearly see that, it will delete all the records in the table.

Voila ! We're done.


For the {lamer | impatient | lazy |etc...}


_id]+OR+TRUE+;+SELECT+item_id+FROM+tblAdressbook+WHERE+item_id=[some id]



Here we used "SELECT item_id from tblAdressbook WHERE item_id=[some id]"

as the second query. Of course it can be more dangerous.

It can be "DROP [some data base]"  if the current SQL user have rights

to do so. Or it can simply delete something

"DELETE from tblMessages"  will delete all the saved incoming

mail messages and it can be really painful. Or it can

add any records to any table (owned by postaci db user).

Variations can be incremented...

Closing words :


Thanks to Umut Gokbayrak for creating such a good webmail

interface for us (Turkish OpenSource Community). I'm sure

he'll make a patch available for this issue A.S.A.P.

Thanks to Selami Aksoy for letting me to use his production

machines for testing (installing new packages, testing PHP codes,

screwing up the total system :))

        About Postaci :


        Postaci (Turkish word for Postman) is a multiplatform GPL' ed 


        software which is database independent (MySQL, mSQL,PostgreSQL,

        Sybase, MS SQL), multilanguage(Turkish, English...), POP3/IMAP

        and fully MIME compatible. While using POP3 mode to fetch 


        it uses database fields to simulate IMAP folders, on which you 


        save, move, delete,read e-mail.


Berk Demir

Association of Turkish Linux Users



(C) 1999-2000 All rights reserved.