How do you prevent SQL injection in LAMP applications? - php

Here are a few possibilities to get the conversation started:
Escape all input upon initialization.
Escape each value, preferably when generating the SQL.
The first solution is suboptimal, because you then need to unescape each value if you want to use it in anything other than SQL, like outputting it on a web page.
The second solution makes much more sense, but manually escaping each value is a pain.
I'm aware of prepared statements, however I find MySQLi cumbersome. Also, separating the query from the inputs concerns me, because although it's crucial to get the order correct it's easy to make a mistake, and thus write the wrong data to the wrong fields.

Prepared statements are the best answer. You have testing because you can make mistakes!
See this question.

as #Rob Walker states, parameterized queries are your best bet. If you're using the latest and greatest PHP, I'd highly recommend taking a look at PDO (PHP Data Objects). This is a native database abstraction library that has support for a wide range of databases (including MySQL of course) as well as prepared statements with named parameters.

I would go with using prepared statements. If you want to use prepared statements, you probably want to check out the PDO functions for PHP. Not only does this let you easily run prepared statements, it also lets you be a little more database agnostic by not calling functions that begin with mysql_, mysqli_, or pgsql_.

PDO may be worth it some day, but it's not just there yet. It's a DBAL and it's strengh is (supposedly) to make switching between vendors more easier. It's not really build to catch SQL injections.
Anyhow, you want to escape and sanatize your inputs, using prepared statements could be a good measure (I second that). Although I believe it's much easier, e.g. by utilizing filter.

I've always used the first solution because 99% of the time, variables in $_GET, $_POST, and $_COOKIE are never outputted to the browser. You also won't ever mistakenly write code with an SQL injection (unless you don't use quotes in the query), whereas with the second solution you could easily forget to escape one of your strings eventually.
Actually, the reason I've always done it that way was because all my sites had the magic_quotes setting on by default, and once you've written a lot of code using one of those two solutions, it takes a lot of work to change to the other one.

Related

Is escaping enough protection against sql injection in codeigniter

I read that escaping input is not enough protection against sql injection.
Then, I saw that codeigniter does not use prepared statements.
It uses escape and bind (which is still just escape) when executing queries.
Would this be enough protection?
If not, should I avoid Query Class and use prepared PDO queries manually?
From everything I've seen, PDO and prepared queries are the thing to pursue now. Seeing alot of PHP posts on here the majority of the comments are telling people to switch to more secure ways of accessing and inserting data into your database in the way of PDO. It is extremely well documented and once you grasp the fundamentals of it, it is very easy to see how it can be used further. TL:DR Escape = bad. PDO = Good
PDO documentation is also here that gives you a huge knowledge base of 'how to's ' which are very easy to follow and well written PDO Manual
Yes you are right in your assumption to avoid the builtin query class, and to use PDO with prepared queries.
Don't use things that are not prepared, unless you're making a plugin, then for the sake of future users you might consider using the builtins to allow easier debugging for them, but still then, consider using a more secure prepared statement supported way.
You really don't want to be the plugin author responsible for a weakness in a site.

PDO vs MYSQLI, Prepared Statemens and Binding Parameters

I have this very question to clear things up. I read some documentation and comments around but still somethings are just not clear enough.
I understand PDO offers more drivers which would certainly is a plus if you would ever change your database type.
As said on another post, PDO doesnt offer true prepared statements but mysqli does so it would be safer to use MYSQLI
Benchmarks looks similar, (did not test it myself but checked around on the web for a few benchmarks)
Being object oriented is not an issue for me since mysqli is catching up. But would be nice to benchmark procedural mysqli vs PDO since procedural is supposed to be slightly faster.
But here is my question, with prepared statement, do we have to use parameter binding with the data we use in our statement? good practice or have to? I understand prepared statements are good perfermance-wise if you run the same query multiple times but it is enough to secure the query itself? or binding parameters is a must? What exactly do the binding parameters and how it works to protect the data from sql injection? Also would be appreciated if you point our any misunderstanding about the statements I made above.
In short,
Binding is a must, being a cornerstone of protection, no matter if it is supported by a native driver or not. It's the idea of substitution that matters.
The difference is negligible in either safety and performance.
Performance is the last thing to consider. There is NO API that is considerable slower than other. It is not a class or a function that may cause whatever performance problem but a data manipulation or a bad algorithm. Optimize your queries, not mere functions to call them.
If you are going to use a raw bare API, then PDO is the only choice. While wrapped in a higher level class, mysqli seems more preferable for mysql.
Both mysqli and PDO lack bindings for the identifiers and keywords. In this case a whitelist-based protection must be implemented. Here is my article with the ready made example, Adding a field name to the SQL query dynamically

Is using prepared statements a best practice? [duplicate]

I'm re-engineering a PHP-driven web site which uses a minimal database. The original version used "pseudo-prepared-statements" (PHP functions which did quoting and parameter replacement) to prevent injection attacks and to separate database logic from page logic.
It seemed natural to replace these ad-hoc functions with an object which uses PDO and real prepared statements, but after doing my reading on them, I'm not so sure. PDO still seems like a great idea, but one of the primary selling points of prepared statements is being able to reuse them… which I never will. Here's my setup:
The statements are all trivially simple. Most are in the form SELECT foo,bar FROM baz WHERE quux = ? ORDER BY bar LIMIT 1. The most complex statement in the lot is simply three such selects joined together with UNION ALLs.
Each page hit executes at most one statement and executes it only once.
I'm in a hosted environment and therefore leery of slamming their servers by doing any "stress tests" personally.
Given that using prepared statements will, at minimum, double the number of database round-trips I'm making, am I better off avoiding them? Can I use PDO::MYSQL_ATTR_DIRECT_QUERY to avoid the overhead of multiple database trips while retaining the benefit of parametrization and injection defense? Or do the binary calls used by the prepared statement API perform well enough compared to executing non-prepared queries that I shouldn't worry about it?
EDIT:
Thanks for all the good advice, folks. This is one where I wish I could mark more than one answer as "accepted" — lots of different perspectives. Ultimately, though, I have to give rick his due… without his answer I would have blissfully gone off and done the completely Wrong Thing even after following everyone's advice. :-)
Emulated prepared statements it is!
Today's rule of software engineering: if it isn't going to do anything for you, don't use it.
I think you want PDO::ATTR_EMULATE_PREPARES. That turns off native database prepared statements, but still allows query bindings to prevent sql injection and keep your sql tidy. From what I understand, PDO::MYSQL_ATTR_DIRECT_QUERY turns off query bindings completely.
When not to use prepared statements? When you're only going to be running the statement once before the db connection goes away.
When not to use bound query parameters (which is really what most people use prepared statements to get)? I'm inclined to say "never" and I'd really like to say "never", but the reality is that most databases and some db abstraction layers have certain circumstances under which they won't allow you to bind parameters, so you're forced to not use them in those cases. Any other time, though, it will make your life simpler and your code more secure to use them.
I'm not familiar with PDO, but I'd bet it provides a mechanism for running parametrized queries with the values given in the same function call if you don't want to prepare, then run as a separate step. (e.g., Something like run_query("SELECT * FROM users WHERE id = ?", 1) or similar.)
Also, if you look under the hood, most db abstraction layers will prepare the query, then run it, even if you just tell it to execute a static SQL statement. So you're probably not saving a trip to the db by avoiding explicit prepares anyhow.
Prepared statements are being used by thousands of people and are therefore well-tested (and thus one can infer they are reasonably secure). Your custom solution is only used by you.
The chance that your custom solution is insecure is pretty high. Use prepared statements. You have to maintain less code that way.
The benefits of prepared statements are as follows:
each query is only compiled once
mysql will use a more efficient transport format to send data to the server
However, prepared statements only persist per connection. Unless you're using connection pooling, there would be no benefit if you're only doing one statement per page. Trivially simple queries would not benefit from the more efficient transport format, either.
Personally I wouldn't bother. The pseudo-prepared statements are likely to be useful for the safe variable quoting they presumably provide.
Honestly, I don't think you should worry about it. However, I remember that a number of PHP data access frameworks supported prepare statement modes and non-prepare statement modes. If I remember correctly, PEAR:DB did back in the day.
I have ran into the same issue as you and I had my own reservations, so instead of using PDO I ended up writing my own light-weight database layer that supported prepares and standard statements and performed correct escaping (sql-injection prevention) in both cases. One of my other gripes with prepares is that sometimes it is more efficient to append some non-escapable input to a statement like ... WHERE id IN (1, 2, 3...).
I don't know enough about PDO to tell you what other options you have using it. However, I do know that PHP has escaping functions available for all database vendors it supports and you could roll your own little layer on top of any data access layer you are stuck with.

php: clear input data before inserting it into mysql database

I'm wondering what's the best way to celar input data before inserting it into a mysql database.
There are a lot of function: trim, addslashes, mysql_real_escape_string and so on.
At this moment i'm using this simple function:
function filter($var){
$data = preg_replace('/[^a-zA-Z0-9]/','',$var);
$data = trim(addslashes($data));
return $data;
}
What's the best way to do it? Thanks
to be on the safe side, when dealing with mysql, mysql_real_escape_string() -- always use this. always.
Using mysql_real_escape_string() is enough for security reasons. Another way to do it is using prepared statements.
But you should check what information in what type you want in your database. There are several functions and language constructs you could use: Typecasts, filter_*() functions, int_val(), abs(), trim(), and a whole lot more.
I suggest you take a look at prepared statements that pretty much protect you against all form of SQL Injection.
The parameters to prepared statements don't need to be quoted; the driver automatically handles this. If an application exclusively uses prepared statements, the developer can be sure that no SQL injection will occur (however, if other portions of the query are being built up with unescaped input, SQL injection is still possible).
The best thing is to do multiple things:
Validate data
Clean data
escape date
The validation is to check whether the data you've got makes any sense. For instance if you expect a birth date you check whether the format is correct and maybe even whether the date amkes sense. This not only has security benefits but also prevents some (not all) errors of wrong data. The tools there depend on the case, regular expression (preg_match) are often a good choice.
Cleaning data is often not really needed, but nice, for instance if a user types in some value use trim() to split of some whitespaces, which might be mistakes from copy and paste or such. This has no security benefit but improves the overall quality of your data. Which is good.
Both of these things should be done early in your script. While "early" depends on your achitecture. Sometimes it makes sense to clean first an validate then or doing it at once (preg_replace)
Then when sending data of to a database or putting it in HTML or any of these things oyu have to escape it accordingly to the system you are using. You should do that for all data, even when you verfied the format beforehand to be on the safe side. When talking to mysql these are the real_escape_string functions for instance, for HTML it is htmlentities() or htmlspecialchars(). with databases it is also a good idea too look into prepared statements, either PDO->prepare + execute() or mysqli->prepare() +execute()

When *not* to use prepared statements?

I'm re-engineering a PHP-driven web site which uses a minimal database. The original version used "pseudo-prepared-statements" (PHP functions which did quoting and parameter replacement) to prevent injection attacks and to separate database logic from page logic.
It seemed natural to replace these ad-hoc functions with an object which uses PDO and real prepared statements, but after doing my reading on them, I'm not so sure. PDO still seems like a great idea, but one of the primary selling points of prepared statements is being able to reuse them… which I never will. Here's my setup:
The statements are all trivially simple. Most are in the form SELECT foo,bar FROM baz WHERE quux = ? ORDER BY bar LIMIT 1. The most complex statement in the lot is simply three such selects joined together with UNION ALLs.
Each page hit executes at most one statement and executes it only once.
I'm in a hosted environment and therefore leery of slamming their servers by doing any "stress tests" personally.
Given that using prepared statements will, at minimum, double the number of database round-trips I'm making, am I better off avoiding them? Can I use PDO::MYSQL_ATTR_DIRECT_QUERY to avoid the overhead of multiple database trips while retaining the benefit of parametrization and injection defense? Or do the binary calls used by the prepared statement API perform well enough compared to executing non-prepared queries that I shouldn't worry about it?
EDIT:
Thanks for all the good advice, folks. This is one where I wish I could mark more than one answer as "accepted" — lots of different perspectives. Ultimately, though, I have to give rick his due… without his answer I would have blissfully gone off and done the completely Wrong Thing even after following everyone's advice. :-)
Emulated prepared statements it is!
Today's rule of software engineering: if it isn't going to do anything for you, don't use it.
I think you want PDO::ATTR_EMULATE_PREPARES. That turns off native database prepared statements, but still allows query bindings to prevent sql injection and keep your sql tidy. From what I understand, PDO::MYSQL_ATTR_DIRECT_QUERY turns off query bindings completely.
When not to use prepared statements? When you're only going to be running the statement once before the db connection goes away.
When not to use bound query parameters (which is really what most people use prepared statements to get)? I'm inclined to say "never" and I'd really like to say "never", but the reality is that most databases and some db abstraction layers have certain circumstances under which they won't allow you to bind parameters, so you're forced to not use them in those cases. Any other time, though, it will make your life simpler and your code more secure to use them.
I'm not familiar with PDO, but I'd bet it provides a mechanism for running parametrized queries with the values given in the same function call if you don't want to prepare, then run as a separate step. (e.g., Something like run_query("SELECT * FROM users WHERE id = ?", 1) or similar.)
Also, if you look under the hood, most db abstraction layers will prepare the query, then run it, even if you just tell it to execute a static SQL statement. So you're probably not saving a trip to the db by avoiding explicit prepares anyhow.
Prepared statements are being used by thousands of people and are therefore well-tested (and thus one can infer they are reasonably secure). Your custom solution is only used by you.
The chance that your custom solution is insecure is pretty high. Use prepared statements. You have to maintain less code that way.
The benefits of prepared statements are as follows:
each query is only compiled once
mysql will use a more efficient transport format to send data to the server
However, prepared statements only persist per connection. Unless you're using connection pooling, there would be no benefit if you're only doing one statement per page. Trivially simple queries would not benefit from the more efficient transport format, either.
Personally I wouldn't bother. The pseudo-prepared statements are likely to be useful for the safe variable quoting they presumably provide.
Honestly, I don't think you should worry about it. However, I remember that a number of PHP data access frameworks supported prepare statement modes and non-prepare statement modes. If I remember correctly, PEAR:DB did back in the day.
I have ran into the same issue as you and I had my own reservations, so instead of using PDO I ended up writing my own light-weight database layer that supported prepares and standard statements and performed correct escaping (sql-injection prevention) in both cases. One of my other gripes with prepares is that sometimes it is more efficient to append some non-escapable input to a statement like ... WHERE id IN (1, 2, 3...).
I don't know enough about PDO to tell you what other options you have using it. However, I do know that PHP has escaping functions available for all database vendors it supports and you could roll your own little layer on top of any data access layer you are stuck with.

Categories