Reading some questions and answers of SQL queries on SO, I saw this answer , which suggests that you can convert untrusted user input to hex, which by its very nature does not require escaping of any type and, therefore, completely and completely avoids the SQL feature -injection .
Which layer of database abstraction you use (PDO, mysqli, mysql, Pear DB, etc.) does not matter .
An example of a typical work request:
$DBH = new PDO('mysql:host=127.0.0.1;dbname=test', 'test', 'testpassword'); // could have been: //$bookTitle = bin2hex($_GET['title']); $bookTitle = bin2hex('Catch-22'); $query = "SELECT * from `books` WHERE `title` = UNHEX('$bookTitle')"; foreach ($DBH->query($query) as $row) { echo "\n<br />\n"; print_r($row); echo "\n<br />\n"; }
I have included enough code here to quickly run the test if you have a database with a table, for example:
CREATE TABLE `books` (`id` INT, `title` VARCHAR(100), `author` VARCHAR(100)) ENGINE=InnoDB CHARACTER SET='utf8'; INSERT INTO `books` VALUES(1, 'Catch-22', 'Joseph Heller');
Of course, this is simplified: usually you need to introduce validation, deactivate work and many other abstractions, but we want to focus on the issue - no more fluff than necessary to help provide easily executed examples.
I would like to know if there are technical flaws in this technique. I don’t specifically ask if this method has human shortcomings (futz is easier as a sloppy programmer, since it is clearly not as clean as using parameterized queries).
Yes, we can all agree that parameterized queries are less susceptible to poor programming or unsuccessful oversights. Therefore, please stick to the question - does this method help to avoid SQL injections of all kinds, unconditionally?
Can someone show an example of user input that violates this technique? Even a corner case, some specific MySQL server settings, or an old version of PHP that breaks it?
It is also suitable for whole replacements:
// could have been: //$bookID = bin2hex($_GET['id']); $bookID = bin2hex(1); $query = "SELECT * from `books` WHERE `id` = UNHEX('$bookID')";
Other thoughts:
Using this method, you avoid two calls to the database, as it happens when using (non-emulated) prepared statements (although prepared statements! = Parameterized queries).
Reservations to some other proposed methods begin to cross-look at what is with exceptions in this case, for example this . Does hexadecimal encoding technology take full advantage of chaos-destroying cybercriminals using character set coding tricks and everything else?
It seems that decoding on the database side may be limited to MySQL / MariaDB, although there may be third-party solutions for adding UNHEX () to PostgreSQL (or - not sure - in some databases, you could use a different method of placing hexadecimal literals in the query without using any UNHEX function)