1

We did a scan on our web page for vulnerabilities. We received a critical Blind SQL injection in the following query. I am using the prepared statements. What else I can do to prevent SQL Injection attack? Please let me know. Here is my example code. I appreciate any suggestions.

$first_name = $_POST["first-name"];
$middle_name = $_POST["middle-name"];
$last_name = $_POST["last-name"];

$qry = $pdo_conn->prepare('INSERT INTO table1(first_name, last_name, middle_initial) VALUES (?, ?, ?)');
$qry->execute(array($first_name, $last_name, $middle_name));
Andy Lester
  • 91,102
  • 13
  • 100
  • 152
nav100
  • 2,923
  • 19
  • 51
  • 89
  • 1
    Do you also have the POST data that triggerd the Blind SQL injection? – Raymond Nijland Aug 19 '13 at 15:01
  • I am already using PDO object. I have researched on the web before posting this question. Please let me know if there is anything wrong. – nav100 Aug 19 '13 at 15:01
  • @RandomSeed - Note that OP is already using prepared statements – Mark Baker Aug 19 '13 at 15:02
  • Yes, we see that you already use bound parameters. Maybe it would help if you explained the "blind sql" injection a bit more precisely. – mario Aug 19 '13 at 15:02
  • 1
    https://www.owasp.org/index.php/Blind_SQL_Injection – Mark Baker Aug 19 '13 at 15:04
  • 1
    how do you know that query is the culprit? are you sure that this wasn't reported as a false positive? – Karoly Horvath Aug 19 '13 at 15:05
  • What version of MySQL? are you using emulated prepares, or real prepared statements? try turning emulation off, since you're using PDO (PDO emulates the prepares by default) – Elias Van Ootegem Aug 19 '13 at 15:10
  • @Elias Van Ootegem not true.. "Prepared statements are so useful that they are the only feature that PDO will emulate for drivers that don't support them. This ensures that an application will be able to use the same data access paradigm regardless of the capabilities of the database." source http://php.net/manual/en/pdo.prepared-statements.php – Raymond Nijland Aug 19 '13 at 15:13
  • We are using '5.5.21' – nav100 Aug 19 '13 at 15:16
  • I'm assuming 5.5.21 is the MySQL version – Mark Baker Aug 19 '13 at 15:17
  • @MarkBaker ... and therefore I consider this snippet safe from the usual SQL injection. Not sure what is meant by "blind SQL injection" though. – RandomSeed Aug 19 '13 at 15:17
  • 1
    @RandomSeed - it should be safe, I get very concerned at the possibility that a prepared statement is no longer safe – Mark Baker Aug 19 '13 at 15:18
  • 1
    @RaymondNijland: Yes, but [they're always emulated for mysql](http://lxr.php.net/xref/PHP_5_4/ext/pdo_mysql/mysql_driver.c#590), unless you disable the emulation manually... – Elias Van Ootegem Aug 20 '13 at 06:11

3 Answers3

0

I am not familiar with the concept of "blind SQL injection", but from what I understand, it works just like the usual injection of SQL code as we all know of (only the interpretation of the result is different).

Since you are using prepared statements, all potentially harmful SQL code will be escaped, and I wouldn't worry about this warning, probably a false positive. Disclaimer: I am not a lawyer security consultant.

RandomSeed
  • 29,301
  • 6
  • 52
  • 87
0

IF it's a real code you posted here, there is no injection vulnerability. Neither of "blind" nor of any other type.

No improvement required for this code.

You need to find yourself a better scanner which raise no false alarms.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • because of PDO::ATTR_EMULATE_PREPARES i was wondering what the default was ive found it in the PHP source code unsigned emulate_prepare:1; C bitfield that the PDO MYSQL driver always using emulated prepares... that worries me a bit not found (jet) why this is the case.. maybe PDO is rendering on default client side prepare statements what could be unsafe too do.. i strongly advise to use ->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); and always define a charset – Raymond Nijland Aug 19 '13 at 18:03
  • Emulation mode doesn't matter at all. – Your Common Sense Aug 19 '13 at 18:13
-1

you can also do it like this:

$qry = $pdo_conn->prepare('INSERT INTO table1(first_name, last_name, middle_initial) VALUES (?, ?, ?)');

 $qry->bindParam(1,$first_name);
 $qry->bindParam(2,$middle_name);
 $qry->bindParam(3,$last_name);

$first_name = strip_tags(mysqli_real_escape_string($qry,$_POST["first-name"]));
$middle_name = strip_tags(mysqli_real_escape_string($qry,$_POST["middle-name"]));
$last_name = strip_tags(mysqli_real_escape_string($qry,$_POST["last-name"]));

$qry->execute();

for more help on Blind sql injection refer : Sql Injection and Blind SQL Injection

Rahul
  • 1,181
  • 1
  • 11
  • 20
  • 1
    mysql_* functions are deprecated as off PHP 5.5.?. And strip_tags strips html tags and php tags doesn't protect against SQL injections... – Raymond Nijland Aug 19 '13 at 15:17
  • yes you are right but it doesent mean we cant use it from 5.1 onward tand before 5.5 and for ur kind info depreciated doesnot mean obsolete – Rahul Aug 19 '13 at 15:19
  • Deprecated might not mean "obsolete", but sometimes things are deprecated because they are obsolete which is the case here. `mysql_` has been replaced by PDO and `mysqli_` – Quentin Aug 19 '13 at 15:22
  • 4
    Mixing bindParam and mysql_real_escape_string is just stupid though. If `mysql_real_escape_string` is doing *anything* in that code, it is causing things to be double escaped, which is definitely not desirable. – Quentin Aug 19 '13 at 15:23
  • Stripping tags **after** preparing data to be inserted into a database is equally awful. You escape data as the last thing you do before inserting it into a database. – Quentin Aug 19 '13 at 15:23