I've used a mysql_real_escape_string till now but it seems that It's not working at GoDaddy Hostings. How should I clean up the string for a database? I've found a PDO::quote but the manual says
"If you are using this function to build SQL statements, you are strongly recommended to use PDO::prepare() to prepare SQL statements with bound parameters instead of using PDO::quote() to interpolate user input into an SQL statement. Prepared statements with bound parameters are not only more portable, more convenient, immune to SQL injection, but are often much faster to execute than interpolated queries, as both the server and client side can cache a compiled form of the query."
Is that means that prepare + bind_params are doing the same thing?
Sorry for my English.
Unfortunately, PHP manual often being unclear, wrong or deceiving.
Prepared statements with bound parameters are
more portable (not true)
more convenient (that's the only true statement),
immune to SQL injection (quote() makes things immune as well),
often much faster to execute (a mere lie)
So, you can use either way, but prepared statements let you have the shorter code:
$id = $pdo->quote($id);
$name = $pdo->quote($name);
$stm = $pdo->query("SELECT * FROM t WHERE id=$id AND name=$name");
vs.
$stm = $pdo->query("SELECT * FROM t WHERE id=? AND name=?");
$stm->execute(array($id,$name));
Though that's not the only reason: please refer to some explanations I made on Why one should use prepared statements
Related
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.
I have following code (simple version of it):
$query = "SELECT *
FROM text
WHERE MATCH (text) AGAINST ('".$pdo->quote($_GET["q"])."' IN BOOLEAN MODE);";
Is there any way to overcome the quote()-function and inject SQL into the query - or is quote() 100% safe?
Thank you very much!
PDO::quote() places quotes around the input string (if required) and escapes special characters within the input string, using a quoting style appropriate to the underlying driver.
So it would appear it protects against SQL injection.
Although, prepared statements guarantee SQL injection protection as we can read from PHP manual:
If you are using this function to build SQL statements, you are strongly recommended to use PDO::prepare() to prepare SQL statements with bound parameters instead of using PDO::quote() to interpolate user input into an SQL statement. Prepared statements with bound parameters are not only more portable, more convenient, immune to SQL injection, but are often much faster to execute than interpolated queries, as both the server and client side can cache a compiled form of the query.
You can read a lot more about it at http://php.net/manual/en/pdo.quote.php
I wanted to know if prepared query is as safe as one that is not prepared. Below are two examples, one for SELECT and one for UPDATE.
First line is the not prepared and second is the prepared query.
SELECT examples:
$userDetails = $connection->query("SELECT * FROM Users WHERE Name='$username'")->fetch();
$userDetails = $connection->prepare('SELECT * FROM Users WHERE Name=?');
$userDetails->execute(array($username));
$userDetails = $userDetails->fetch();
UPDATE examples:
$query = $connection->query("UPDATE Users SET SessionID='$sessionID' WHERE Name='$username'")->execute();
$query = $connection->prepare("UPDATE Users SET SessionID=? WHERE Name=?");
$query->execute(array($sessionID, $username));
Should I use the long way of doing it or is the one that takes only one line to do worse?
From the documentation
The prepared statement execution consists of two stages: prepare and
execute. At the prepare stage a statement template is sent to the
database server. The server performs a syntax check and initializes
server internal resources for later use.
Repeated execution
A prepared statement can be executed repeatedly. Upon every execution
the current value of the bound variable is evaluated and sent to the
server. The statement is not parsed again. The statement template is
not transferred to the server again.
A prepared statement has its advantages of checking syntax and repeated execution. Prepared statements are especially preferred when your sql is generated dynamically using variables
you can read more in this SO post MySQLi: query VS prepare
No, they are not the same with respect to security.
The versions where you copy variables into the string are risking SQL injection vulnerabilities. It depends how you handle the variables. It is safe if you process them with PDO::quote() before copying them into the SQL string, but if your developers forget to do this, it's unsafe.
It's a commonly held myth that prepared statements are slower. They're not -- in fact, they can be faster, at least from the perspective of the RDBMS.
However, the extra code run in your PHP application has some overhead, so there is some performance penalty in the PHP runtime. But it's a pretty small amount of overhead. I wouldn't worry about it.
Just use prepared statements!
They're easier to code correctly.
They're as safe as quoting, if not safer.
They have no disadvantage for SQL execution performance.
Use the quick version for unique statement that will not be used regulary with same structure.
Use the long version in loops for example.
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.
I understand from my recent use of PHP-PDO over the last few months that you can do a PREPARE statement and then run the query. In fact I can see the usefulness of this if I'm going to either SELECT on a complex join, varying the where conditions, a repeated number of times.
Or, similarly, if I was wanting to insert multiple records.
However, if I know I only want to run a statement once, shouldn't I just EXECUTE the query? I'm basically querying the database twice.
It depends if you have any input you need to escape to prevent sql injection.
According to the manual on PDO::quote:
If you are using this function to build SQL statements, you are
strongly recommended to use PDO::prepare() to prepare SQL statements
with bound parameters instead of using PDO::quote() to interpolate
user input into an SQL statement. Prepared statements with bound
parameters are not only more portable, more convenient, immune to SQL
injection, but are often much faster to execute than interpolated
queries, as both the server and client side can cache a compiled form
of the query.
here are the benchmarks: http://jnrbsn.com/2010/06/mysqli-vs-pdo-benchmarks
prepared statements are close to within the margin of error in terms of slowdown and therefore can be considered insignificant for most purposes.