Is hexing input sufficient to sanitize SQL Queries?

会有一股神秘感。 提交于 2019-12-06 03:55:43

问题


I was reading last night on preventing SQL injections, and I ran across this answer:

How can I prevent SQL injection in PHP?

The comments from 'Your Common Sense' made it sound like that was dysfunctional/unsafe. However, in my (albeit limited) testing, I found that php's "bin2hex($var)" worked with anything I threw at it - literal number, number string, string of text - even when matching a numerical (tinyint) column.

My question is this: Is there a way to inject SQL when every user input is sanitized via hexing it? In essence, any time a query was made, it would look something like this:

$query="SELECT * FROM table WHERE someidentifier=UNHEX('".bin2hex($unsafe_user_input)."') LIMIT 1"

Basically translating to:

SELECT * FROM table WHERE someidentifier=UNHEX('0b99f') LIMIT 1

Are there any holes in this type of security?

PS - I'm not just looking for answers like "Why not just use PDO or MySQLi with prepared statements?" It may fall under the vast evil of preemptive optimization, but I'd rather not double my query overhead (and yes, I do understand that it can be faster with multiple identical queries, but that's not a situation I often encounter).


回答1:


Is there a way to inject SQL when every user input is sanitized via hexing it?

If you knew why an SQL injection occurs, you would be able to answer this question yourself.


Let’s see. The CWE describes SQL injections (CWE-89) as follows:

The software constructs all or part of an SQL command using externally-influenced input […], but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command […]

Furthermore:

Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.

So basically: externally-influenced inputs in a generated SQL query are not interpreted as intended. The important part here is: not interpreted as intended.

If a user input is intended to be interpreted as a MySQL string literal but it isn’t, it’s an SQL injection. But why does it happen?

Well, string literals have a certain syntax by which they are identified by the SQL parser:

A string is a sequence of bytes or characters, enclosed within either single quote (“'”) or double quote (“"”) characters.

Additionally:

Within a string, certain sequences have special meaning […]. Each of these sequences begins with a backslash (“\”), known as the escape character. MySQL recognizes the escape sequences shown in Table 9.1, “Special Character Escape Sequences”.

Additionally, to be able to use quotes within string literals:

There are several ways to include quote characters within a string:

  • A “'” inside a string quoted with “'” may be written as “''”.
  • A “"” inside a string quoted with “"” may be written as “""”.
  • Precede the quote character by an escape character (“\”).
  • A “'” inside a string quoted with “"” needs no special treatment and need not be doubled or escaped. In the same way, “"” inside a string quoted with “'” needs no special treatment.

As all these latter mentioned sequences are special to string literals, it is necessary that any data, that is intended to be interpreted as a string literal, is properly processed to conform to these rules. This means in particular: if any of the mentioned characters are intended to be used in a string literal, they have to be written as one of the mentioned ways.

So if you look at it from this way, it is not even a question of security but simply of processing data so that they are being interpreted as intended.

The same applies to the other literals as well as other aspects of SQL.


So what about your question?

My question is this: Is there a way to inject SQL when every user input is sanitized via hexing it? In essence, any time a query was made, it would look something like this:

$query="SELECT * FROM table WHERE someidentifier=UNHEX('".bin2hex($unsafe_user_input)."') LIMIT 1"

Yes, that would be safe from SQL injections. bin2hex returns a string that contains only hexadecimal characters. And neither of these characters require a special treatment when using them in a MySQL string literal.

But seriously, why would anyone want to use these cumbersome formatting technique when there libraries and frameworks that supply convenient techniques like parameterized/prepared statements?




回答2:


While i'm not familiar with hexing, i have successfully used Base64 to prevent mysql injections in the past from various scripts.




回答3:


Are there any holes in this type of security?

There are no holes but no advantages as well. Conventional string formatting is equally safe but without all this useless hexing/unhexing stuff.

So, bloating your queries with this unhex stuff is just superfluous.

As of yonder answer, initially it was written without unhexing and thus failed with numbers, which made it unusable. While after adding unhex it become just useless and superfluous.




回答4:


$query="SELECT * FROM table WHERE someidentifier=UNHEX('".bin2hex($unsafe_user_input)."') LIMIT 1"

This is a simple and certain answer for protecting against SQL injection using PHP and MySQL.

I've seen comments that suggest that it is still possible to be open to SQL injection with prepared or parameterized SQL. I don't see any reason to fuss with all that when this solution is simple and it works.

I've seen the arguments about CPU time and memory usage, but since this is typically used for user input typed on a screen, who cares about the RAM usage or CPU cycles (gasp!). The user types in 500 characters, the hex version is a thousand characters. Unless your server has a hundred thousand people doing this at the exact same moment, you aren't going to see much difference.

Creating clear, obvious, maintainable code is worth a few CPU cycles and some RAM.

And the technique is so simple, it is easy to remember. It is also unlikely to break or develop holes as PHP continues to evolve.



来源:https://stackoverflow.com/questions/22567944/is-hexing-input-sufficient-to-sanitize-sql-queries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!