Sanitizing MySQL Queries without preprared statements (PHP + old mysql module) - php

Note: I've looked at this question: Preventing SQL injection without prepared statements (JDBC) . And as I somewhat expected... the answer is to use prepared statements. I'm in a different set of circumstances... so I'd like to know the best path for this.
I'm using a downloaded script (phpsimplechat) where the author wrote his own simple SQL layer (notice: it supports PostgreSQL and MySQL). Unfortunately, I've ran some tests on it and it is vulnerable to SQL Injection. The script does everything I want simply from a features standpoint, so I'd like to salvage it.
Fortunately, it is open source... but I'd rather not rewrite all of the SQL queries to use prepared statements in phpsimplechat. The 3rd party library uses its own SQL layer instead of PDO... and under that uses the older mysql module (thus, I can't use prepared statements. Even if I changed mysql -> mysqli, I have to deal with "dbQuery" layer he put on top of all of his code). I do NOT need the PostgreSQL code, so answers can be MySQL specific.
I've read that addslashes is insufficient to protect against all SQL Injection attempts. Is mysql_real_escape_string safe to use?

Yes, mysql_real_escape_string is guaranteed to be safe if you use it correctly, i.e. make sure that all strings appearing in queries are escaped.

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.

Disable multiple statements in PHP PDO

Is there a way to disable multiple statement queries in PDO? A method that works with all the drivers supported?
Alternatively, is there any well known filter that detect multiple statements in a string?
I know that prepared statements can better prevent SQL injection risks, there are reasons why I can't use them in this case.
You are barking the wrong tree.
Multiple statement is not a synonym for SQL injection. It's just a subset, a very small one, out of zilliards other possible ways to exploit an injection.
Therefore you should protect from injection, not multiple statement. For this, a query that is sent to database API have to be 100% hardcoded in your script. To achieve that, always substitute all the variables in the query with placeholders.
Yes, there is a way to disable multiple statement queries, at least for PDO MySQL, you can do it by using the PDO::MYSQL_ATTR_MULTI_STATEMENTS constant [1,2]; the constant exists as of PHP 5.5.21 and PHP 5.6.5.
I have looked for an equivalent for PostgreSQL, SQLite and MS SQL Server but I haven't found it. However, according to my tests, PDO PostgreSQL and SQLite don't allow multiple statement queries, while pdo_sqlsrv does. I haven't found official documentation about this, though, so it could depend on my driver version or other factors.
References:
[1] http://php.net/manual/en/ref.pdo-mysql.php
[2] https://bugs.php.net/bug.php?id=68424

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.

How do protect yourself against SQL injection when using prepared statements/store procedures in PHP?

I've been looking at how best to protect against sql injection in PHP/mysql beyond just using the mysqli/mysql real escape since reading this Is mysql_real_escape_string enough to Anti SQL Injection?
I have seen this very good thread How can I prevent SQL injection in PHP?
I use to do alot of ms sql server stuff on the desktop/internal tools, we always wrote stored procedures to protect against this so I read up on the equivalent in PHP/mysql using PDO http://php.net/manual/en/pdo.prepared-statements.php
In the above there is the line :
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).
I've been lead to believe that PDO do protect against sql injection attacks so can anyone provide a instance where PDO isnt sufficient from a security standpoint?
You can still get SQL injections from stored procedures which are internally using the PREPARE syntax (in MySQL) to create dynamic SQL statements.
These need to be done with extreme care, using QUOTE() as necessary.
Ideally, we should not need to use PREPARE in stored routines, but in certain cases it becomes very difficult to avoid:
Prior to MySQL 5.5, the LIMIT clause cannot use non-constant values.
Lists used in an IN() clause cannot be (sensibly) parameterised, so you need to use dynamic SQL if this pattern is used
It is sometimes desirable to use dynamically generated ORDER BY clauses.
etc
In the case where it is necessary to use PREPARE, then I would recommend, in order of preference:
If something is an INT type (etc) it is not susceptible to SQL injection, and you can place the value into the query without a problem (e.g. for LIMIT)
String values can be placed into an #variable before the EXECUTE, or passed in to the EXECUTE clause
List-values (for example for IN()) need to be checked for validity.
Finally, QUOTE() can be used to quote string values, which can be useful in some cases
It's not the structure you use (stored procedures, prepared statements etc.) that is decisive, but whether you are at any point concatenating SQL together using unchecked user input. For example, you can execute dynamic SQL from within a stored procedure, in which case the danger is still there.
The easiest way (from the injection-avoidance point of view) is to use SPs or PSs with bound-in variables: these do not need to be checked as they will be recognized as values to go within a predefined placeholder.

PHP SQL injection prevention without parameter binding [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to prevent SQL injection in PHP?
I am working for a video streaming website for my college library. I am using PHP and MySql. I have not used any parameterized queries in this project.
Recently I came to know about SQL injections. Now that my code is almost done and I have to submit the project in the next two days, how can I now ensure that my code is not SQL injection prone?
Converting the whole thing in to a parameterized interface is what I can't do now. What should I do now to avoid SQL Injections on my website?
The basic idea to prevent SQL injections (if not using Prepared Statements) is to escape your data.
When you inject some expected integer value into an SQL query, make sure it's an integer, using intval().
When you have a decimal/numeric field in your table, use floatval().
And when you have a string (char, varchar, text) field in your table, use the function provided by your API to escape strings :
mysql_real_escape_string()
mysqli_real_escape_string()
PDO::quote()
I really recommend that you go back and do it right with parameterized queries. It is the only solid path towards security. It likely won't take too long to do this once you get started.
You should also know that websites are never "finished". When you launch a site, your work has just begun. Fixing security troubles as you learn about them is part of it, and this is no different.
You'll want to make sure any user provided inputs that get used in SQL queries are escaped using the PHP function mysql_real_escape_string and if you are letting people submit text to run htmlentities on the provided text so XXS isn't possible. If possible, white-list user provided input and discard anything else
This is just touching the surface of what you can do but look into query escaping and preventing cross site scripting.
Use PDO (or alternatively mysqli or some abstraction layer) and prepared statements.
Quick example:
$pdo = new PDO($dsn);
$stmt = $pdo->prepare("SELECT name FROM users WHERE id = ?");
$stmt->execute(array($unsafe_id));
$name = $stmt->fetchColumn();
In this example, $unsafe_id will be safe to use. To quote the manual page:
Calling PDO::prepare() and
PDOStatement::execute() for statements
that will be issued multiple times
with different parameter values
optimizes the performance of your
application by allowing the driver to
negotiate client and/or server side
caching of the query plan and meta
information, and helps to prevent SQL
injection attacks by eliminating the
need to manually quote the parameters.
PDO will emulate prepared
statements/bound parameters for
drivers that do not natively support
them, and can also rewrite named or
question mark style parameter markers
to something more appropriate, if the
driver supports one style but not the
other.

Categories