Which SQL inject methods aren't "destroyed" by mysql_real_escape_string();? - mysql

Is there a list of SQL injection methods which can't be protected with just using mysql_real_escape_string(); with utf8 encoding?
For integer, I'm using intval();
Is it secure enough?
For those who think I want to get "tutorial" to hack anyone: No, I won't. I just want to know how to make my applications more secure, and I want to know if they're secured 99% against hackers

If given a valid database connection, mysql_real_escape_string() is supposed to be safe for string data under all circumstances (with the rare exception described in this answer).
However, anything outside a string, it won't escape:
$id = mysql_real_escape_string($_GET["id"]);
mysql_query("SELECT * FROM table WHERE id = $id");
is still vulnerable, because you don't have to "break out" of a string to add an evil additional command.

There are not many sql injection methods. They are always due to input not being sanitized and escaped properly. So, While mysql_real_escape_string() will make any string safe to be included in a database query, you should follow the following avoidance techniques to protect your data and users from sql injection.
Never connect to the database as a superuser or as the database owner. Use always customized users with very limited privileges.
Check if the given input has the expected data type.
If the application waits for numerical input, consider verifying data with is_numeric(), or silently change its type using settype()
Quote each non numeric user supplied value that is passed to the database with the database-specific string escape function. So mysql_real_escape_string() will make all strings safe to be included in an SQL query to a mysql database
You could also learn to use stored procedures and prepared statements which tend to be very safe but have other impacts
See also: PHP page on SQL injection

There are many things that may not get protected by standard methods (e.g. string escaping, int casting), also depending on the version of software you use. For example, utf-8 is quite an issue by itself, as a tiny example (among many) you should make sure the request is valid utf-8 (or convert it into utf-8). See an example.
As the undead bane of websites, I think that MySQL injection protection cannot be squeezed into a single SO answer, hence I'm including these links as general starting points.
http://ferruh.mavituna.com/sql-injection-cheatsheet-oku/
And also : Search for mysql injection utf8

Related

SQOOP Export to MySQL

Trying to do sqoop export from HDFS to MYSQL. Getting mapper error because of different date format between input file vs MySQL. Input file have data in mm/dd/yyyy format where in SQL it is date. I guess MySQL is yyyy-mm-dd.
Because of same getting an error as:
caused by: java.lang.RuntimeException: Can't parse input data: '2/18/2019'
My limitation as the source is from different provider and we can not request them to change it. So in this situation what options do i have? Any suggestions
edit
Unfortunately this answer may not be for you. If you are using a program that you don't have control over the source for, this won't help you.
I'll leave it up only because it is a common question that I see with people new to rdbms programming.
Original answer
Why are you treating dates and times as strings? For that matter why are you building SQL for each row? On the MySql side there is a better way to handle that.
Most RDBMS support the concept of a Prepared Statement, although the implementation differs by vendor. Java had support through jdbc for all of the major vendors flavor of prepared statement, so you don't need to worry about the implementation details.
Every time you execute SQL the database engine goes through several phases before the data is applied or returned. The first and most time consuming phase, called the "prepare" phase, is to analyze the SQL string and computer the ideal access path to complete it with. 50 to 80 percent of the SQL "execution" time is spent in this "Prepare" phase.
A simple optimization is to recognize that the ideal access path in a mature database rarely varies, which allows the programmer to prepare the statement once, return a handle to the access path, then pass only the handle and it's parameters across the wire from the application to the database. This minimizes overheads of access path computation, data type conversions, and network communication while automatically protecting from SQL injection attacks and taking care of such administrivia as date formatting.
In Java, this is represented with the PreparedStatement class.
Always use prepared statements. If used properly, they will eliminate 50 to 80% of the overheads of each database call. They also allow you to choose more simply by using native java types and simply passing the value into the execution with the PS.
Using PreparedStatement also eliminates much of the need to sanitize inputs. By it's nature, you don't need to worry about special characters, apart from those the target will reject (example: dropping a character with a codeine greater than 127 into a database that was built for ASCII only on a platform that enforces character set).
If you need to take input as String, and convert to Date, use java's DateFormat class.

Are the escape functions in the Node.js mysql package sufficient enough to securely query a mysql database (without the use of prepared statements)?

According to Node.js' mysql package documentation:
In order to avoid SQL Injection attacks, you should always escape any user provided data before using it inside a SQL query. You can do so using the mysql.escape(), connection.escape() or pool.escape() methods.
I cannot find any documentation / reference to using prepared statements with mysql, except for in a reference to using '?' characters. It states the following:
Alternatively, you can use ? characters as placeholders for values you would like to have escaped...
This looks similar to prepared statements in MySQL, however it really
just uses the same connection.escape() method internally.
From my experience with talking to other developers, the general consensus in the developer community is that prepared statements are the ONLY safe way to perform mysql queries from Node.js however, as you can see with the mysql package, there is no obvious support for prepared statements. However, it is indicated that their method for avoiding SQL injection is via the usage of the escape functions.
My Question:
Are the escape functions in the mysql package sufficient enough to securely query a mysql database (without the use of prepared statements)?
Escaping is actually just as safe as using parameterized queries, if you do it consistently.
But it's recommended to use parameters because it makes your code simpler. Therefore developers are probably more likely to do it.
If the Node.js library makes it just as convenient as parameters, but implements it internally by modifying query strings, replacing the ? marks with the parameter values, then you're good.
For what it's worth, Python's MySQL driver does this too, and also PHP's PDO extension when the "emulate prepares" option is in effect. As long as those libraries are well-tested, it should be safe.
FWIW, both escaping and parameters is limited in SQL injection prevention, because in both cases, you can only protect values that you would combine with your SQL query. You cannot protect identifiers (like table names, or column names), or SQL keywords, or expressions, etc. In these cases, just be careful that you have vetted any dynamic content before combining it with your SQL query.
See also:
Preventing SQL injection in Node.js
Difference between real_escape_string and prepare()?

Mysql Database Attacks other than Sql Injection

I am using mysqli prepared statements and bound variables.
Then to prevent sql injection, am I need to do anything else(eg: data type validation, filtering, sanitize, string escape etc ) with user input ?
Is there any other way of attacking MySql database other than Sql Injection ?
To prevent SQL injection you have to format your query properly.
Every literal that have to be added to the query dynamically, have to be properly formatted.
Not only data literals like strings and numbers but all of them, including operators and identifiers.
The only proper way to make values formatted is prepared statements.
For the identifiers and operators you will need also filtering, to let only allowed ones into query.
Whatever user input should not be involved at all. It's destination, not source that matters.
Is there any other way of attacking MySql database other than Sql Injection ?
sure thing. But the topic is too broad to make you secured by means of a forum post. Better hire a DBA.

protecting against malicious sql injection

I have a bunch of perl CGIs that take params and use their values in various DBI mySql queries.
Is there any way that a malicious user can do harm (or steal data) from my system if I don't allow any user submitted values that contain the words select, insert, delete, or update to be used as parameters and as long as I wrap all the varchar user provided values in single quotes?
I realize this question is very similar to others asked, but the others all seem to point to various PHP solutions, and I'm not using PHP, so, please forgive the redundancy, or point me to an associated question that answers this specific question.
The correct way to handle this in Perl use to use placeholders in all your SQL queries. Passing user-supplied data via DBI placeholders will ensure that everything is properly quoted. (That doesn't guarantee that it's secure, of course, but it will prevent SQL injection.)
Use parameterized queries. Then the user input is not part of the command at all, which is the only reliable way to know the command won't be modified.

Are dynamic mysql queries with sql escaping just as secure as prepared statements?

I have an application which would greatly benefit by using dynamic mysql queries in combination with mysql (mysqli) real escape string. If I ran all data received from the user through mysql real escape would it be just as secure as using mysql prepared statements?
Yes, but a qualified yes.
You need to properly escape 100% of the input. And you need to properly set character sets (If you're using the C API, you need to call the mysql_set_character_set() instead of SET NAMES). If you miss one tiny thing, you're vulnerable. So it's yes, as long as you do everything right...
And that's the reason a lot of people will recommend prepared queries. Not because they are any safer. But because they are more forgiving...
Definitely NO.
While question in the title is ambiguous and can be interpreted as "Are dynamic mysql queries with every it's part properly formatted..." and thus have a positive answer, the question in the body is not:
If I ran all data received from the user through mysql real escape would it be just as secure as using mysql prepared statements?
If you look to this question closer, you will understand that this is just a magic quotes incarnation! The very purpose of this disgraced, deprecated and removed feature is exactly to "run all user input through escape".
Everyone knows nowadays that magic quotes are bad. Why positive answer then?
Okay, it seems that it needs to be explained again, why bulk escaping is bad.
The root of the problem is a quite strong delusion, shared by almost every PHP user:
Everyone have a strange belief that escaping do something on "dangerous characters" (what are they?) making them "safe" (how?). Needless to say that it's but a complete rubbish.
The truth is:
Escaping do not "sanitize" anything.
Escaping has nothing to do with injections.
Escaping has nothing to do with user input.
Escaping is merely a string formatting and nothing else.
When you need it - you need it despite of injection possibility.
When you don't need it - it won't help against injection even a little.
Speaking of difference with prepared statements, there is at least one issue (which already mentioned many times under sql-injection tag):
a code like this
$clean = mysql_real_escape_string($_POST['some_dangerous_variable']);
$query = "SELECT * FROM someTable WHERE somevalue = $clean";
will help you NOT against injection.
Beause escaping is just a string formatting facility, not injection preventer by any means.
Go figure.
However, escaping have something in common with prepared statements:
Them both doesn't guarantee you from injection if
you are using it only against notorious "user input", not as a strict rule for the building ANY query, despite of data source.
in case you need to insert not data but identifier or a keyword.
To be safe in these circumstances, see my answer explaining FULL sql injection protection how-to
Long story short: you can consider yourself safe only if you make 2 essential corrections and one addition to your initial statement:
If I ran all data received from the user through mysql real escape and always enclose it in quotes (and, as ircmaxell mentioned, mysqli_set_charset() is used to make mysqli_real_escape string() actually do it's work (in such a rare occasion of using some odd encoding like GBK)) would it be just as secure as using mysql prepared statements?
Following these rules - yes, it would be as secure as native prepared statements.
I think #ircmaxell got it right on.
As a follow-up, be on the lookout for this kind of thing.
I used to do it all the time:
<?php
//sanitize the dangerous posted variable...
$clean = mysql_real_escape_string($_POST['some_dangerous_variable']);
//...and then forget to use it!
$query = "SELECT * FROM someTable WHERE somevalue = '{$_POST['some_dangerous_variable']}'";
?>
And when I say "used to do it", what I mean is that I eventually gave up and just started using prepared statements!