PHP Prepared Statement to delete all records - php

How do you delete all contents of a table in PHP MySQL using prepared statement? Do I have to use prepared statement to be safe or does using $deleteall = mysqli_query($conn,"DELETE FROM mytable;"); works with no difference?
Is this how it's supposed to be done:
$stmt = $conn->prepare("DELETE FROM mytable");
$stmt->execute();

There's no point in using prepared statements when you don't have parameters.
Prepared statements exist to make if efficient to execute a statement multiple times, possibly with different arguments. They also help with SQL injection prevention: you don't have to remember to apply quoting and escaping manually. But if you're going to run something only once there are no parameters, don't bother with prepared statements.

You may want to delete records with criteria parameters so the best way to do it:
$sqlQuery = "DELETE FROM TABLE_NAME WHERE id=?";
$statement = $conn->prepare($sqlQuery);
$statement->bind_param("i", $memberId);
$statement->execute();

Use this way, it is working fine on me. Hope it will help you.
$stmt= 'DELETE from mytable';
$result = $conn->prepare($stmt);
$result->execute();

Related

Code isn't passing a security check, how do I make my parameter binding better?

My code has to pass a security check but it didn't because of a sql injection risk. They have requested that I use parameters which I thought I already used, so now I wonder how to make my code better?
$imgId = $_POST["imgId"];
$stmt = $link->prepare("SELECT * FROM my_table WHERE image_id = ?");
$stmt->bind_param("s", $imgId);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
This is one of my sql statements, each and every one is structured like this one.
So my question is first of all is my code susceptible to sql injections and secondly how do I make it more secure?
maybe you should try regular expressions on your IDimg if u know what the expected input to be, and pregmatch it

PDO emulate off, binding same value multiple times

I have the following bit of code in PHP7. I'm using PDO to connect to MySQL.
With PDO prepared statements emulation on, this code works successful:
$query = $db_con->prepare('SELECT * FROM matches WHERE matches.home_team_id=:team_id OR matches.away_team_id=:team_id');
$query->bindValue(':team_id', $team_id, PDO::PARAM_STR);
$query->execute();
return $query->fetchAll();
But with true PDO prepared statements (emulation off), the previous code gives an error that not enough values were bound. I'm forced to do the following:
$query = $db_con->prepare('SELECT * FROM matches WHERE matches.home_team_id=:team_id OR matches.away_team_id=:team_id2');
$query->bindValue(':team_id', $team_id, PDO::PARAM_STR);
$query->bindValue(':team_id2', $team_id, PDO::PARAM_STR);
$query->execute();
return $query->fetchAll();
This works, but is there any way I don't have to declare the same variable twice with true prepared statements? I have a lot of these queries, and would like to replace them all to use true prepared statements.
As someone asked in the comments: why do I want emulation off? I didn't really have a preference, but now it seems that true prepared statements are more strict than emulated statements. Is my understanding correct that is is better to develop with true prepared statements to guarantee it will work with both settings?
There is a way by change the query
$query=$db_con->prepare('SELECT*FROM matches WHERE :team_id in(home_team_id,away_team_id)');
$query->bindValue(':team_id', $team_id, PDO::PARAM_STR);
$query->execute();
This may not desirable, but it declare variable at once for case.
Hope this helpful.
A simple solution is to use a counter. In that way you can keep emulation off and still bind the same value multiple times without the need to count how many times you've used it, or renumber when you change the query.
$count=0;
$query = $db_con->prepare(
'SELECT * FROM matches WHERE
matches.home_team_id=:team_id'.(++$count).' OR
matches.away_team_id=:team_id'.(++$count)
);
for($i=1; $i<($count+1) ;++$i){
$query->bindValue(':team_id'.$i, $team_id, PDO::PARAM_STR);
}
$query->execute();
return $query->fetchAll();

Understanding PDO Prepared Statements and Binding Parameters

From experience and also having been told constantly the benefits of using prepared statements and binding my parameters, I have constantly used those two techniques in my code, however I would like to understand exactly the purpose of each of those two techiques:
From my understanding of prepared statements:
$sql = "SELECT * FROM myTable WHERE id = ".$id;
$stmt = $conn->prepare($sql);
$stmt->execute();
The previous code should create a sort of a buffer in the database with the query I proposed. Now FROM MY UNDERSTANDING (and I could be very wrong), the previous code is insecure, because the string $sql could be anything depending on what $id actually is, and if $id = 1; DROP TABLE myTable;--, I would be inserting a malicious query even though I have a prepared statement.
FROM MY UNDERSTANDING this is where binding my parameters com in. If I do the following instead:
$sql = "SELECT * FROM myTable WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
$stmt->execute();
The database should know exactly all the parts of the sql statement before hand:
SELECT these columns: * FROM myTable and WHERE id = "a variable that was input by the user", and if "a variable that was input by the user" != a variable, the query fails.
I have been told by some my understanding is correct, and by others that it is false, could someone please let me know if I am wrong, correct, or missing something? And elaborate as much as you want, all feedback is greatly appreciated!
You're correct that the first case is insecure. It's important to understand though, that preparing a statement only has value if you are using variable data, and/or executing the same query repeatedly. If you are executing plain statements with no variables, you could simply do this:
$sql = "SELECT * from myTable WHERE this_column IS NOT NULL";
$result = $conn->query($sql);
And end up with a PDOStatement object to work with, just like when you use PDO::exec().
For your second case, again, you're largely correct. What's happening is the variable passed to the database is escaped and quoted (unless you specify otherwise with the third argument to PDOStatement::bindParam(), it's sent as a string which is fine for most cases.) So, the query won't "fail" if bad data is sent. It behaves exactly as if you had passed a valid number that didn't exist as an ID in the database. There are, of course, some edge cases where you are still vulnerable even with a correctly prepared statement.
Also, to make life easier, you can use prepared statements like this, to do implicit binding:
$sql = "SELECT * FROM myTable WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute([":id"=>$id]);
Or even like this, with un-named parameters:
$sql = "SELECT * FROM myTable WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->execute([$id]);
Naturally, most of this has been explained in the comments while I was typing up the answer!

Mysqli prepared statement (SQL injection prevention)

after stopping the use of deprecated mysql_* functions, I switched to mysqli. But then, I noticed that non-prepared statements are non-secure against SQL injection. Then, I changed again my code.
What I had was the following function that checks if the variable $ID exists in the database and prints the value of title for that row:
function showPostTitle($ID, $mysqli) {
$result = $mysqli -> query("SELECT ID, title FROM blog where ID = $ID");
$row = $result -> fetch_array(MYSQLI_BOTH);
echo $row['title'];
}
I changed it to this:
function showPostTitle($ID, $mysqli) {
$stmt = $mysqli -> prepare("SELECT ID, title FROM blog WHERE ID = ?");
$stmt -> bind_param("i", $ID);
$stmt -> execute();
$stmt -> bind_result($ID, $title);
$stmt -> fetch();
print_r($title);
$stmt -> free_result();
}
My question is: is this the correct way to implement prepared statements? Plus, am I safe now from SQL Injections? Big thanks to whoever will answer this question :)
Your mysqli logic seems fine, there are some examples in the PHP manual here in case you have not seen them.
Why are you selecting the ID when not consuming it though? Also you don't really need to bind a result when it's only going to have one row returned in the full result set as I assume will happen in this case (ID is unique index in the table), use get_result instead.
Using mysqli prepare will protect against all the common injection attacks but not 0-day style stuff which hasn't made it to the driver yet.
Take a look at this post:
Are PDO prepared statements sufficient to prevent SQL injection?
It's using PDO instead of MySQLi, which is solving the same problem by creating prepared statements.
Sorry for not answering your question, but just wanted to provide a resource for you to consider.

Is mysql_real_escape_string() necessary when using prepared statements?

For this query, is necessary to use mysql_real_escape_string?
Any improvement or the query is fine ?
$consulta = $_REQUEST["term"]."%";
($sql = $db->prepare('select location from location_job where location like ?'));
$sql->bind_param('s', $consulta);
$sql->execute();
$sql->bind_result($location);
$data = array();
while ($sql->fetch()) {
$data[] = array('label' => $location);
}
The query speed is important in this case.
No, prepared queries (when used properly) will ensure data cannot change your SQL query and provide safe querying. You are using them properly, but you could make just one little change. Because you are using the '?' placeholder, it is easier to pass params through the execute method.
$sql->execute([$consulta]);
Just be careful if you're outputting that to your page, SQL parameter binding does not mean it will be safe for display within HTML, so run htmlspecialchars() on it as well when outputting.

Categories