When should I use prepared statements? - php

Originally I used mysql_connect and mysql_query to do things. Then I learned of SQL injection, so I am trying to learn how to use prepared statements. I understand how the prepare and execute functions of the PDO class are useful to prevent SQL injection.
Are prepared statements only necessary when a users input is stored into a database? Would it be okay to still use mysql_num_rows, since I don't really run the risk of being hacked into by using this function? Or is it more secure to use prepared statements to do this? Should I use prepared statements for everything that involves using MySQL? Why?

tl/dr
Always. 100% of the time, use it. Always; and even if you don't need to use it. USE IT STILL.
mysql_* functions are deprecated. (Notice the big red box?)
Warning This extension was deprecated in PHP 5.5.0, and it was removed
in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be
used. See also MySQL: choosing an API guide and related FAQ for more
information. Alternatives to this function include:
mysqli_connect()
PDO::__construct()
You'd be better off using PDO or MySQLi. Either of those 2 will suffice as compatible libraries when using prepared statements.
Trusting user input without prepared statements/sanitizing it is like leaving your car in a bad neighborhood, unlocked and with the keys in the ignition. You're basically saying, just come on in and take my goodies
You should never, and I mean never, trust user input. Unless you want this:
In reference to the data and storing it, as stated in the comments, you can never and should never trust any user related input. Unless you are 101% sure the data being used to manipulate said databases/values is hard-coded into your app, you must use prepared statements.
Now onto why you should use prepared statements. It's simple. To prevent SQL Injection, but in the most straight forward way possible. The way prepared statements work is simple, it sends the query and the data together, but seperate (if that makes sense haha) - What I mean is this:
Prepared Statements
Query: SELECT foo FROM bar WHERE foo = ?
Data: [? = 'a value here']
Compared to its predecessor, where you truncated a query with the data, sending it as a whole - in turn, meaning it was executed as a single transaction - causing SQL Injection vulnerabilities.
And here is a pseudo PHP PDO example to show you the simplicity of prepared statements/binds.
$dbh = PDO(....); // dsn in there mmm yeahh
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
Taken from PHP Manual for PDO Prepared Statements
More Reading
How can I prevent SQL-injection in php?
What is SQL-injection? (Simple Terms)

TL;DR Use prepared statements 100% of the time if your SQL makes use of data or input of any kind
You seem to have a slight confusion. First, please don't use mysql_*; the mysql_* functions are outdated, deprecated, and insecure. Use MySQLi or PDO instead. Second, mysql_num_rows has nothing to do with prepared statements and is not a PDO feature, anyway. You prepare the statement before you run the query, not after it when you want to count rows.
As for when to prepare statements, #Mike'Pomax'Kamermans nailed it in the comments. If you ever, even once, use any data that has ever been touched by a user -- even a supposedly trusted user -- or is generated by any kind of third party or third-party application, including a browser, use prepared statements. Only if 100% of your data is hard-coded can you trust it.
For example, you cannot trust:
Usernames
Passwords
Email addresses
User comments
Phone numbers
Dates
Search strings
Browser client strings
Credit card numbers
File names for uploads
And any other kind of input created by a user or that a user could manipulate.
You should validate all of these (for example, check that an email address is really an email address) before putting them in a database, of course. But even then, using prepared statements is the safe way to go.

There is a two solution for this-
01- Use Prepared Statements
To prevent SQL injections we will have to use something called prepared statements which uses bound parameters. Prepared Statements do not combine variables with SQL strings, so it is not possible for an attacker to modify the SQL statement. Prepared Statements combine the variable with the compiled SQL statement, this means that the SQL and the variables are sent separately and the variables are just interpreted as strings, not part of the SQL statement.
02- Prepared Statements with mySQLi.
Using the methods in the steps below, you will not need to use any other SQL injection filtering techniques such as mysql_real_escape_string(). This is because with prepared statements it is not possible to do conventional SQL injection.
eg -
$name = $_GET['username'];
if ($stmt = $mysqli->prepare("SELECT password FROM tbl_users WHERE name=?")) {
// Bind a variable to the parameter as a string.
$stmt->bind_param("s", $name);
// Execute the statement.
$stmt->execute();
// Get the variables from the query.
$stmt->bind_result($pass);
// Fetch the data.
$stmt->fetch();
// Display the data.
printf("Password for user %s is %s\n", $name, $pass);
// Close the prepared statement.
$stmt->close();
}
You can find more about this form - http://www.wikihow.com/Prevent-SQL-Injection-in-PHP

Mysql_* already has been deprecated so better to switch mysqli_* or PDO
For prevent sql injection (mysql) :- How can I prevent SQL injection in PHP?.
And prepared statements(These are SQL statements that are sent to and parsed by the database server separately from any parameters. ) use on your every user generated query data.
like on posting data you matching/getting records to db with query. so mean when you fire a query with form data.

Related

How do I make a prepared statement for simple view? [duplicate]

Originally I used mysql_connect and mysql_query to do things. Then I learned of SQL injection, so I am trying to learn how to use prepared statements. I understand how the prepare and execute functions of the PDO class are useful to prevent SQL injection.
Are prepared statements only necessary when a users input is stored into a database? Would it be okay to still use mysql_num_rows, since I don't really run the risk of being hacked into by using this function? Or is it more secure to use prepared statements to do this? Should I use prepared statements for everything that involves using MySQL? Why?
tl/dr
Always. 100% of the time, use it. Always; and even if you don't need to use it. USE IT STILL.
mysql_* functions are deprecated. (Notice the big red box?)
Warning This extension was deprecated in PHP 5.5.0, and it was removed
in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be
used. See also MySQL: choosing an API guide and related FAQ for more
information. Alternatives to this function include:
mysqli_connect()
PDO::__construct()
You'd be better off using PDO or MySQLi. Either of those 2 will suffice as compatible libraries when using prepared statements.
Trusting user input without prepared statements/sanitizing it is like leaving your car in a bad neighborhood, unlocked and with the keys in the ignition. You're basically saying, just come on in and take my goodies
You should never, and I mean never, trust user input. Unless you want this:
In reference to the data and storing it, as stated in the comments, you can never and should never trust any user related input. Unless you are 101% sure the data being used to manipulate said databases/values is hard-coded into your app, you must use prepared statements.
Now onto why you should use prepared statements. It's simple. To prevent SQL Injection, but in the most straight forward way possible. The way prepared statements work is simple, it sends the query and the data together, but seperate (if that makes sense haha) - What I mean is this:
Prepared Statements
Query: SELECT foo FROM bar WHERE foo = ?
Data: [? = 'a value here']
Compared to its predecessor, where you truncated a query with the data, sending it as a whole - in turn, meaning it was executed as a single transaction - causing SQL Injection vulnerabilities.
And here is a pseudo PHP PDO example to show you the simplicity of prepared statements/binds.
$dbh = PDO(....); // dsn in there mmm yeahh
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
Taken from PHP Manual for PDO Prepared Statements
More Reading
How can I prevent SQL-injection in php?
What is SQL-injection? (Simple Terms)
TL;DR Use prepared statements 100% of the time if your SQL makes use of data or input of any kind
You seem to have a slight confusion. First, please don't use mysql_*; the mysql_* functions are outdated, deprecated, and insecure. Use MySQLi or PDO instead. Second, mysql_num_rows has nothing to do with prepared statements and is not a PDO feature, anyway. You prepare the statement before you run the query, not after it when you want to count rows.
As for when to prepare statements, #Mike'Pomax'Kamermans nailed it in the comments. If you ever, even once, use any data that has ever been touched by a user -- even a supposedly trusted user -- or is generated by any kind of third party or third-party application, including a browser, use prepared statements. Only if 100% of your data is hard-coded can you trust it.
For example, you cannot trust:
Usernames
Passwords
Email addresses
User comments
Phone numbers
Dates
Search strings
Browser client strings
Credit card numbers
File names for uploads
And any other kind of input created by a user or that a user could manipulate.
You should validate all of these (for example, check that an email address is really an email address) before putting them in a database, of course. But even then, using prepared statements is the safe way to go.
There is a two solution for this-
01- Use Prepared Statements
To prevent SQL injections we will have to use something called prepared statements which uses bound parameters. Prepared Statements do not combine variables with SQL strings, so it is not possible for an attacker to modify the SQL statement. Prepared Statements combine the variable with the compiled SQL statement, this means that the SQL and the variables are sent separately and the variables are just interpreted as strings, not part of the SQL statement.
02- Prepared Statements with mySQLi.
Using the methods in the steps below, you will not need to use any other SQL injection filtering techniques such as mysql_real_escape_string(). This is because with prepared statements it is not possible to do conventional SQL injection.
eg -
$name = $_GET['username'];
if ($stmt = $mysqli->prepare("SELECT password FROM tbl_users WHERE name=?")) {
// Bind a variable to the parameter as a string.
$stmt->bind_param("s", $name);
// Execute the statement.
$stmt->execute();
// Get the variables from the query.
$stmt->bind_result($pass);
// Fetch the data.
$stmt->fetch();
// Display the data.
printf("Password for user %s is %s\n", $name, $pass);
// Close the prepared statement.
$stmt->close();
}
You can find more about this form - http://www.wikihow.com/Prevent-SQL-Injection-in-PHP
Mysql_* already has been deprecated so better to switch mysqli_* or PDO
For prevent sql injection (mysql) :- How can I prevent SQL injection in PHP?.
And prepared statements(These are SQL statements that are sent to and parsed by the database server separately from any parameters. ) use on your every user generated query data.
like on posting data you matching/getting records to db with query. so mean when you fire a query with form data.

Do I need to escape my variables if I use MySQLi prepared statements?

If I use MySQLi prepared statements like below:
$stmt = $con1->prepare("UPDATE Login SET Session='LoggedOut' where Session=?");
$stmt->bind_param('s',$Session);
$stmt->execute();
$stmt->close();
Do I still need to escape my variables like $Session with mysqli_real_escape_string(); like below:
$Session = mysqli_real_escape_string($con1, $_COOKIE['Session']);
$stmt = $con1->prepare("UPDATE Login SET Session='LoggedOut' where Session=?");
$stmt->bind_param('s',$Session);
$stmt->execute();
$stmt->close();
No, if you use prepared statements everywhere in your application you are safe from SQL injection. However, an important "gotcha" is 2nd order injection attacks which happen when some queries use prepared statements and others don't.
According to this answer of a similar question on SO:
prepared statements / parameterized queries are sufficient to prevent 1st order injection on that statement. If you use un-checked dynamic sql anywhere else in your application you are still vulnerable to 2nd order injection.
In summary, prepared statements create a separation between the data being sent and the SQL query itself, ensuring that the data can not be misinterpreted as the SQL query. However, an attacker can still enter SQL as data, and although it will not be executed when it is first stored if you are using prepared statements, you must still use caution when retrieving said results. Prepared statements protect your application in that particular place, but because SQL is still allowed to be stored in the database, your application is unsafe if you're later using that data without parameterization.
Nope you don't.
This is the only answer you need.
All the muddled talk in the other answer is just irrelevant. The guy is trying to tell you that if you are foolish enough not to use prepared statements all over the place, then you're in danger. Which is quite obvious, and irrelevant to a prepared statement itself.

PHP PDO versus MySQL Extension Questions

Currently, I am developing my first website. Right now, I am implementing PHP's MySQL extensions. From what I've been reading, however, using PHP's PDO would be a much better way to go for several reasons such as the use of placeholders and so forth.
After going over some of the code, I am curious about a few things. As an example, say I create a connection and query as such:
$pdo = new PDO('mysql:host=localhost;dbname=something','root','abc');
$sql="select id from users where username = :username and password = :password";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(":username",$_POST['username']);
$stmt->bindParam(":password",$_POST['password']);
$stmt->execute();
First, does $stmt->execute(); actually execute the entire query? And if so, why? If that is the case, my assumption would be that, in a way, it is inherently connected to the the prepared statements and therefore it is binded to the prepared sql statement.
Also, it is quite obvious that prepared statements are better protected against sql injection. My questions is at what point is user input sanitized within PDO. To explain, in the MySQL extensions, functions such as mysql_real_escape_string() had to be hardcoded when sanitizing.
If there are any other intricacies of using PDO that don't exist when using MySQL extensions, I am curious to know.
Any feedback is appreciated.
Also, it is quite obvious that prepared statements are better protected against sql injection. My questions is at what point is user input sanitized within PDO. To explain, in the MySQL extensions, functions such as mysql_real_escape_string() had to be hardcoded when sanitizing.
Ideally, it's delivered directly to the database driver as data (alliteration! Awesome, always). However, if PDO has to emulate prepared statements, then it's done when the query is executed.
First, does $stmt->execute(); actually execute the entire query? And if so, why? If that is the case, my assumption would be that, in a way, it is inherently connected to the the prepared statements and therefore it is binded [sic] to the prepared sql statement.
Yes. $stmt->execute() is connected to $stmt because you're calling it on $stmt. I'm not really sure how to further explain that.

PHP & MySQL: Creating your own Prepared statement without using MySQLi and/or PDO

Like my title, I want to know how to create a prepared statement without using MySQLi or PDO. The main point is learning the process of creation and it's security. I have nearly "ZERO-KNOWLEDGE" in this. Tried googling the topic but it seems that my googling skills have failed me. I've blindly learned that prepared statement is pretty secure from some websites but I do not see the actual point that it is secure. Can some of you clarify why it is? That would be a big help. I have my own assumption that creating a prepared statement is simply creating a function that receive string and replace all special character with str_replace like:
$org_sql = 'SELECT * FROM `my_table` WHERE `table_id`=?';
$prepared_sql = replaceQueryString($org_sql, 10);
function replaceQueryString($str, $replace) {
// Do the replace where ? will be replaced by $replace here.
return $str;
}
But I wonder if that will raise the level of the security, it looks rather plain to me.
If you don't want to waste time answering this just point me to where the resource is available. So in summarize.
How to create a MySQL prepared statement?
Why it is secure?
Many thanks.
Prepared statements are created and executed by the database, not by your code. To implement them yourself, you would have to implement the MySQL protocol and talk to the database directly.
Here's how prepared statements work:
You send the query, with placeholders, to the RDBMS
The RDBMS stores the query and pre-computes an execution plan
You separately tell the database to execute the statement, and pass the values to bind to its parameters
The RDBMS executes its stored plan using the values
There are two types of prepared statements, the emulated prepared statements and the native prepared statements. What you are doing is emulating the prepared statements.
1.How to create a MySQL prepared statement?
In php level, you could only emulate the prepared statement by replacing the placeholder with secure values. (Ex: quote the string, escape the special char, and so on...)
2.Why it is secure?
Because the prepared statements prevent the sql injection.
PS:
PDO has the option of PDO::ATTR_EMULATE_PREPARES, which enables or disables emulation of prepared statements.

Would prepared statements completely secure my website from MySQL injection?

I'm using prepared statements and MySQLi with my queries to protect against injection attacks. Would prepared statements remove the need for mysql_real_escape_string entirely? Is there anything else I should consider when securing my site?
As long as you're using the prepared statements correctly they will. You have to make sure you're binding all the external variables and not putting them directly in the query.
For example
$stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=" . $name);
This statement is being prepared, but it doesn't use one of the bind methods so it does no good. It is still vulnerable to SQL injection.
To fix that make sure to bind everything...
$stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {
$stmt->bind_param("s", $city);
I'm using prepared statements and MySQLi with my queries to protect against injection attacks.
Don't do it. Don't use prepared statements to protect from anything. It is not what prepared statements are for. It is just to make your queries syntactically correct. And, as a side effect, a syntactically correct query is invulnerable to any attack too.
So, just use it to put data into query.
Would prepared statements remove the need for mysql_real_escape_string entirely?
That's wrong from the mysql_real_escape_string side. this function do not protect you from anything. If you just apply this function to your data, it wouldn't make it "safe". this function works for the quoted strings only.
While yes, using prepared statements makes this function obsolete, as well as other plain SQL assembling rules. It actually does the job you think mysql_real_escape_string do. It does actually make any data safe (for SQL).
Is there anything else I should consider when securing my site?
Sure.
Not to talk of whole city - it's another and way too broad question, but of SQL query again:
Prepared statements makes only data safe.
Thus, you have to take care of dynamical non-data parts of the query, such as field names, operators, etc. Prepared statements won't help you with them.

Categories