Title: how to block multiple query in 1 time
Tags: php;mysql;pdo;sql-injection
Question: I'm using php+PDO+mysql to SELECT users, to complete my page I have to get rid of 1 security issue. on each query from server-side I have "SELECT id,first_name,last_name FROM users WHERE $conditions" and the rest is from client side $_POST["conditions"] (the filter) now how can I make sure they don't inject another UPDATE/DELETE/INSERT/SELECT... at the end???
or if you think I'm just doing it all wrong, please tell me, thanks in advance
Comment: example $conditions 'first_name LIKE %blahblah%'

Comment: It's really undesirable to have users fully modify the conditions. What for example someone searches for `login_name LIKE 'a%'` and narrows it down in multiple searches to the full login-name? (next step: password). Have an array with `$searchableColumns`, checkboxes for all of them and on post `foreach($serchableColumns as $c) { if (checkbox checked) { add '$c LIKE ?' to the query } }`

Comment: Can you give an example of $conditions?

Here is the accepted answer: The best and safest approach is to avoid building a query injecting clauses posted from the client.
You should add a "layer" of separation/abstraction between $_POST["conditions"] and $conditions.
Let the client ask what data have to be fetched with a convention you'll decide.
For example $_POST["conditions"] may be empty for "all the users". If $_POST["conditions"] contains a number then the user with matching ID is fetched... That's just a basic example to give the idea, of course.
Then you parse $_POST["conditions"] and build up $conditions accordingly.
As your server-side code builds up $conditions you can then safely inject it in your query.
If you have to take some value (the ID taking the example above) and insert into the query use a prepared statement to do so.
Note that you may find convenient to use more POST variables instead of a single one for defining what user(s) have to be fetched.

Here is another answer: You should know exactly what kind of statements are allowed and act accordingly. For example, let's say that you want to be able to execute 3 different queries depending on the user input:
'id LIKE %param%'
'first_name LIKE %param%'
'last_name LIKE %param%'
You don't want to insert these directly. Instead, you make 2 different POST variables:
$_POST['field'] will select the field and $_POST['param'] will be your search parameter.
A very basic example:
//you can just store all these in array if there are many
//we don't use POST directly, we set a variable depending on it's value
$field="";
if ($_POST['field']=="id") $field="id";
elseif ($_POST['field']=="first_name") $field="first_name";
elseif ($_POST['field']=="last_name") $field="last_name";
if ($field!="") {
$sql = $dbh-&gt;prepare("SELECT `id`, `first_name`, `last_name` FROM `users` WHERE ".$field." LIKE :param");
$sql-&gt;bindParam("param", "%".$_POST['param']."%");
$sql-&gt;execute();
else echo "Error!";
Never trust the user input.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 2, 'CommentCount': 3, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2013:00:12/07/13', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<php><mysql><pdo><sql-injection>', 'Title': 'how to block multiple query in 1 time', 'ViewCount': 93, 'id': 20446084, 'user_AboutMe': None, 'user_AccountId': None, 'user_DisplayName': None, 'user_Reputation': None, 'user_Views': None, 'user_id': None}}