Re: Re: sql injection protection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 26-01-2012 15:46, Haluk Karamete wrote:
when we do b64e and then back b64d, you are saying. we get the org
input all as clear text but this time as a string. because it is now a
string, "(which by definition can not be executed)"

what's the difference between b64e+b64d vs (string) casting then? if
you were to cast the original input into string using (string),
wouldn't you be in the same shoes?

No, it's not. The problem here is that we're using 2 different systems, which have to talk to eachother. They do this via strings.

If you send 'SELECT a FROM b', for PHP that's a string. It doesn't know or even care if this is SQL or what you want to do with it. To PHP it's just a string.

Once it gets to MySQL however, it will look at that string, parse it as SQL and execute it.

Now, if we use:
'SELECT a FROM b; DROP TABLE b'
for PHP, it will still be just a string. Nothing special.
For MySQL however, it will have turned into 2 different operations, which will both be executed. It will first SELECT a FROM b, and then DROP TABLE b.

Can this be resolved by casting the whole query to a string in PHP? No. It's already a string.

However, if you base64_encode a part of the query (the variable part that you're afraid might get replaced by malicious code), it will appear as a string to MySQL. It will recieve the following:
SELECT a FROM b WHERE c='MSc7RFJPUCBUQUJMRSBiIFdIRVJFIDE9JzE=';
instead of:
SELECT a FROM b WHERE c='1';DROP TABLE b WHERE 1='1';

To PHP, both are still strings. But to MySQL, the first is an operation which SELECTs a from b where c has a certain value. The second, does the same, but also drops the table (! WHOA! we Don't want that!!).

Of course, if we change the code to:
SELECT a FROM b WHERE c=BASE64DECODE('MSc7RFJPUCBUQUJMRSBiIFdIRVJFIDE9JzE=');

It will select based on the STRING "1';DROP TABLE b WHERE 1='1" and will not execute it, since it did not recieve it as executable code.

Do you finally understand the difference?

also on another note, if you know the userinput is in UTF-8, ( you
verify that by running mb_detect_encoding($str, 'UTF-8', true); )
This doesn't guarantee anything. You can't see the encoding on a bare string. You can guess what it might be (using a function such as mb_detect_encoding), but it might very well be wrong. If I send you a string like 'abcdef', it may be detected as being ANSII, ISO-8859-11, ISO-8859-16, and a million others. Why? Because encoding is just a way of saying "value X in this string represents character Y", but to know that, you first need to know what codepage / encoding belongs to it. If you don't know that, value 2148 might mean 'C' or 'F' or 'PO'. You don't know, and you don't have any way of figuring this out. That is why it is CRITICAL to know what encoding is being used.

If a UTF-7 encoded string is provided, it may look like a string of crap to you. But when it is interpreted as being in UTF-8 it might suddenly completely change meaning, and contain malicious code. The string itself doesn't change at all, just the interpretation of the string.

When starting a connection, you should make sure that the encoding it works with is the same you're using to construct your strings. So if you're working in UTF-7, make sure MySQL is aswell. Otherwise, you have to make sure to manually recode your strings from UTF-7 to UTF-8.

Hopefuly that makes it more clear to you.

, is
there a situation where you think mysql_real_escape_string would fail
in SQLINjection against string based user input ?  The reason I ask
this about specifically for strings is because it is fairly easy to
validate againsts integers,floats,booleans using the built in
validation filters.... my biggest issue is on strings...

also what do you think about filter_sanitize_string.

and finally, where do you think PHP community plus Rasmus is having a
hard time implementing what you have in mind - that is a one liner
that will do the  inline string interpolation you are talking about..
what's the issue that it hasn't been done before?


There are many ways of getting around the functions mentioned above. Personally I have little experience with HOW you can do it (although I've been forced to patch holes found due to the fact that we did rely on it though). You can search the internet to find out how. We can't really help you there, we can only advise you (as has been done a million times already, though you don't seem to be able to accept the recommendation). If you decide not to accept the recommendation, then don't, and just use your own way. It may bite you after a while though.

Security issues like the one mentioned above are notoriously difficult to eliminate effectively; oneliners rarely if ever suffice.

- Tul

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux