-3

is using PDO more secure that the normal classic "mysql_query" ? or is there other more secure ways to import and export data from mysql db

I heard the using PDO could cause you problems, is it right?

elephantail
  • 15
  • 1
  • 1
  • 5
  • [this blog](http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/) might give you a good understanding. – Jon Apr 06 '13 at 13:16
  • possible duplicate of [How to prevent SQL injection in PHP?](http://stackoverflow.com/questions/60174/how-to-prevent-sql-injection-in-php) – Quentin Apr 06 '13 at 14:37

3 Answers3

1

I'd use PDO with parameters binding rather than simple mysql_query. This will ensure you won't have to deal with SQL injection issues with your project

Here's a simple example i took from php.net docs:

<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>

using pdo this way is definitely more safe. It'll also handle variables casting. I'm using PDO (on the low level with additional abstraction level) in all my current php projects and i never had any problems with that.

zeliboba
  • 46
  • 3
1

In general importing / exporting data from database is not any more or less secure if you would use mysql_query rather than PDO wrapper. The important thing you need to take care of is to secure the insecure source of data. Generally - don't trust anything that comes from user via mechanisms such as GET, POST, COOKIE etc. and is used as parameters for your code - consider it all malicious data and first validate into format you expect.

PDO is "more secure" in a sense that it is easy to parametrize your SQL query and avoid SQL injection type of attacks which are usually the most common types of web attacks. For example:

<?php
$id = (isset(_$GET['id']))? _$GET['id'] : ''; // Possibly unsafe data from user
$dbh = new PDO('mysql:host='.$host.';dbname='.$name, $user, $pass);
$sth = $dbh->prepare("SELECT * FROM `table` WHERE `id`=?");
$sth->execute(array($id));
?>

By using parametrized queries like above where placeholder ? is replaced by specific data query expects there, you effectively prevent SQL injection from happening because PDO then considers data you got from _$GET['id'] as just a "data" instead of something that might be part of a query string (which may be used to cause SQL injection).

If for example you would directly insert GET data by appending it to query like:

$query = "SELECT * FROM `table` WHERE `id`=".$_GET['id'];

This could easily lead to SQL injection. Don't ever do that. That last part of SQL can be used in all sorts of ways to inject additional SQL you never intended to execute if the _$GET variable is not validated or filtered. If in above example user supplied the following string in the _$GET['id'] - "1;DROP TABLE table;" that would effectively drop your table with users - a thing you never intended to do as then a resulting query would look like:

"SELECT * FROM `table` WHERE `id`=1;DROP TABLE table;"

You should do everything you can to prevent getting invalid data in the first place for example if you expect integer you might do:

$id = (isset(_$GET['id']))? _$GET['id'] : ''; // Possibly unsafe data from user
$id = intval($id);  // Make sure the data is integer at all times
if ($id < 0) $id = 0; // Make sure it is positive integer at all times

That way you may ensure the data is in expected format.

By first validating the data, and then using parametrized query to insert into database you ensure in a way multi-layered security which helps you getting rid of invalid entries in your database as well as invalid code behaviour. As suggested by "Your Common Sense" in comments below it doesn't make it absolutely secure for all kinds of attacks but it does decrease their likelihood significantly.

intval is not the only function that can help you with that, you can also examine:

http://php.net/manual/en/function.filter-var.php

What kind of problems regarding PDO are you referring to?

Coder12345
  • 3,431
  • 3
  • 33
  • 73
  • you can easily parameterize your SQL with mysql_query as well – Your Common Sense Apr 06 '13 at 13:21
  • I would opt for PDO as it is a bit easier though. – Coder12345 Apr 06 '13 at 14:09
  • using code from [this answer](http://stackoverflow.com/a/14112684/285587) would be apparently easier than yours. `$res = paraQuery("SELECT * FROM table WHERE id=%d",$_GET['id']);` will take just one line to run a prepared query. – Your Common Sense Apr 06 '13 at 14:29
  • OK, it may look cleaner, but why bother with that when PDO has all of that built in? And the above code is intentionally extended to make it easier to understand, I could make it more condensed but there is no much point in that. – Coder12345 Apr 06 '13 at 14:31
  • PDO hasn't. It lacks many important placeholder types. – Your Common Sense Apr 06 '13 at 14:32
  • BTW, your idea of sanitizing only user input is essentially wrong. A query have to be properly formatted despite of data source. Otherwise injection inevitable – Your Common Sense Apr 06 '13 at 14:33
  • If so, please give example how is your paraQuery function more secure than above validation + parametrized PDO query and how is paraQuery in that sense invulnerable to SQL injection. Essentially, I see it as 2 different ways of getting the same result. I am eager to learn new things if you can provide specific example. – Coder12345 Apr 06 '13 at 14:35
  • paraQuery is not more secure than PDO. The point is that it's no less secure either. And another point: as PDO lacks important placeholder types, you have to "bother" with custom wrapper anyway. And it could be written in mysql_* without a single problem. And be way more secure and easy than PDO. An example of such a wrapper is linked in my answer. – Your Common Sense Apr 06 '13 at 14:45
  • I never said that it is any more or less secure. This is the first sentence in my answer. Personally, I find PDO easier to use as I don't have to invent my own wrappers but it is all standardized and well documented on php.net (and in case of bugs someone else maintains it which has its advantages). Also, being a PHP module, PDO is compiled rather than interpreted as PHP function (which makes it a small bit faster). Lacking placeholder types are a little bit off topic here aren't they? – Coder12345 Apr 06 '13 at 14:47
1

There is nothing essentially secure in the function names you are using.

It's the way using them could be secure (or not). One can make mysql_query no less secure than PDO. And contrary - PDO can easily "could cause you problems" if used improperly.

So, the most secure way to deal with data in mysql query (not database) is:

  1. every dynamical literal should be added to the query via placeholder only
  2. if plcaceholder cannot be used - value have to be whitelisted against hardcoded list of allowed values

As PDO offers support for placeholders out of the box, it is preferred over mysql_query in general. However, this support is very limited, and if you want to have full protection, you have to create your own solution, or use some ready-made library like SafeMySql

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • If you used placeholder without first validating your data that doesn't prevent invalid data entering your database. It is always best to validate first, then use placeholder. Multilayered security always pays off. – Coder12345 Apr 06 '13 at 14:24
  • data validation is irrelevant to SQL injections. mixing it you make yourself vulnerable – Your Common Sense Apr 06 '13 at 14:27
  • Data validation is mentioned in the context if query was INSERT rather than SELECT which might cause invalid data to be placed in the database (I could invent a scenario where this data may be used for second-order SQL injection attack although these attacks are rather unlikely, but we'd be going way off topic, even this is going off topic rapidly). – Coder12345 Apr 06 '13 at 14:42
  • Your idea if protection is ALL wrong. You cannot prevent so-called "second order injection" with just data validation. And shouldn't either. You're looking at the problem from the wrong point of view – Your Common Sense Apr 06 '13 at 14:49
  • I'm sorry but this is no longer constructive discussion so I'll end it here. Thanks for the suggestions and different point of view though. – Coder12345 Apr 06 '13 at 14:59