17

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?

Dharman
  • 30,962
  • 25
  • 85
  • 135
G.SINGH
  • 389
  • 2
  • 3
  • 8
  • 2
    if you can guarantee no part of your codebase ever uses user generated query data, there is very little point. If you have even a single query, there is no point in using two different ways of forming queries. Go with prepared queries for security first, and consistency second. – Mike 'Pomax' Kamermans Jul 28 '14 at 05:27
  • You seem to have a slight confusion. First, please [don't use `mysql_*`](http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php?rq=1); the `mysql_*` functions are outdated, [deprecated](http://us3.php.net/manual/en/intro.mysql.php), and insecure. Use [`MySQLi`](http://us3.php.net/manual/en/book.mysqli.php) or [`PDO`](http://us3.php.net/manual/en/intro.pdo.php) 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. – elixenide Jul 28 '14 at 05:36

4 Answers4

45

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:

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 enter image description here

You should never, and I mean never, trust user input. Unless you want this:

SQL Injection

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

Community
  • 1
  • 1
Darren
  • 13,050
  • 4
  • 41
  • 79
  • @Darren I want to know if I get this right. Is it necessary to use a prepared statement where there are only fixed values? For example somebody needs to approve or deny a request and the only input that person gets is the choice of 2 buttons approve and deny and each on of the buttons writes different values which is fixed. Do I need to use a prepared statement there? **Note:** That page does not gives the user any possibility for users to input any text. – BRoebie Dec 03 '15 at 12:24
  • @BRoebie It's better to be safe than sorry. Anywhere a user can interact with data being passed through (i.e. forms) should essentially be prepared statements. If you're taking said values from input that's easily modifiable from element inspection/etc, then you could be in a lot of trouble. – Darren Dec 03 '15 at 23:34
  • @Darren I agree. I was wondering if I need to use prepared statements if the user could only interact with 2 buttons on the page one would write _request approved_ in the db and the other button would write _request denied_ in the db. (and yes it is a form what I am talking about but all the fields there are readonly fields which can't be modified, only the 2 buttons which I mentioned above with fixed values in the code that are send to the db) – BRoebie Dec 04 '15 at 07:54
  • I know this is very late (painfully so), but I just want to mention that, when talking about 'user input', this means the request that is sent to your page / application, not specifically a webform. Users can do an HTTP request (for instance) directly to your application without ever actually requesting the index (or any other for that matter) page on your website. Please understand how the communication between server and client works because this is CRITICAL – user236800 Jan 02 '21 at 11:26
5

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.

elixenide
  • 44,308
  • 16
  • 74
  • 100
  • I get what you are saying. The reason I mentioned that I am using mysql_num_rows is because I saw this http://stackoverflow.com/questions/11305230/alternative-for-mysql-num-rows-using-pdo and it seemed kind of pointless. If no user data is being processed then mysql_num_rows should be fine right? – G.SINGH Jul 29 '14 at 02:42
  • 1
    Yes; as long as you're certain there's no user data, such as `SELECT COUNT(*) FROM mytable`, you don't have to use prepared statements. Personally, though, I would recommend always using prepared statements; lots of security flaws get introduced when an old query with no user data gets updated and the programmer forgets to use prepared statements for the new query. That's just my opinion. – elixenide Jul 29 '14 at 02:57
1

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

Sri
  • 496
  • 1
  • 5
  • 20
0

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.

Community
  • 1
  • 1
Rakesh Sharma
  • 13,680
  • 5
  • 37
  • 44