Is escaping enough protection against sql injection in codeigniter - php

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.

Related

How to turn off multiple statements in postgres?

I think it is a good idea to turn off multiple statements like this to prevent this type of sql-injection.
Example of multiple statements:
$query = "UPDATE authors SET author=UPPER(author) WHERE id=1;";
$query .= "UPDATE authors SET author=LOWER(author) WHERE id=2;";
$query .= "UPDATE authors SET author=NULL WHERE id=3;";
pg_query($conn, $query);
Is it possible to prevent multiple statements in posgresql settings or for example using posgre's related PHP code?
Or maybe there is any way of parsing SQL queries before passing them to pg_query in order to detect queries which consists of more than one statement?
No, there is no way to disable multi-statements in PostgreSQL. Nor, as far as I know, is there any way to do so in the PHP Pg or PDO PostgreSQL drivers.
They aren't your problem anyway. Disabling multi-statements might be a (slight) SQL injection harm mitigation, but it wouldn't be any real protection. Consider writeable CTEs, for example, or qualifier removal attacks.
Instead, protect your code properly in the first place. Rigorously use parameterized statements instead of string concatenation, so there's no SQL injection opportunity in the first place. It's not hard to avoid SQL injection, you just have to be a little bit sensible with your coding practices.
Use PDO or pg_query_params for all queries, and make sure you don't concatenate text that's come from outside the immediate scope directly into SQL text, use a parameter. Even if it comes from elsewhere in the application and is considered "trusted" ... later refactoring might change that.
I think it is a good idea
It is, actually, not.
You have to prevent injections, not multiple queries.

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

PDO and CodeIgniter - is it secure?

I dont have any previous experience with PDO, so my question may sound too simple.
I heard few times that PDO is better than mysql/mysqli in terms of security ,and since Codeigniter is supporting PDO driver, I decided to make the change in my new project.
but as I'm aware of Codeingiter doesn't use prepared statements, and (I think) it missed the point of using PDO, is that correct, and is it insecure?
So my question: is using PDO driver with codeigniter considered insecure?
And, does that mean I must take care of the basic security by myself?
All query calls are escaped in the simplified $this->db functions, such as delete() and get_where(). This adds some automated security.
If written too slobby, you may grant access to users to edit other users content for instance. So there's no magical solution to full security. The more detailed you are, the more correct your code will work for you.
If you need custom queries, you can do like this:
$int_user_id = 1;
$this->db->query("
SELECT *
FROM users
WHERE id = ?
", array($int_user_id));
Note: To implement IN () and LIKE, you need to escape accordingly, and not insert through array() and ?.
query()
escape()
1. Database Support
The core advantage of PDO over MySQL is in its database driver support. PDO supports many different drivers like CUBRID, MS SQL Server, Firebird/Interbase, IBM, MySQL, and so on.
2. Security
Both libraries provide SQL injection security, as long as the developer uses them the way they were intended. It is recommended that prepared statements are used with bound queries.
3. Speed
While both PDO and MySQL are quite fast, MySQL performs insignificantly faster in benchmarks – ~2.5% for non-prepared statements, and ~6.5% for prepared ones.
From what I know (CodeIgniter newbie ;)) it takes care of security pretty well with ActiveRecords. I don't know if it's using PDO or not, but it's pretty darn easy to use, queries look really clean, and it has query caching.

Preventing SQL injections in 2012

I've had a good read with this question mysqli or PDO - what are the pros and cons?. But I think it's a bit dated. Are prepared statements still the best solution against injections?
I'm going to create a new php interface to access my mysql database so I want to get it right from the start.
Also doesn't pdo slow your query's down a lot?
Use prepared statements/parametrized queries. This is completely safe since you do not mix SQL with data in the same string and you don't have to think about escaping anymore. At least if you don't start making your column/table names dynamic in a way users can modify them.
The advantages you get by using PDO us absolutely worth the minimal performance loss.

How do you prevent SQL injection in LAMP applications?

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.

Categories