Escaping quotes in SQL

According to php.net, I have to use mysql_real_escape_string () and turn off magic quotes because it is deprecated.

So I turned it off and used mysql_real_escape_string (), but is it enough to use it, as in the following code?

$value = "It Time!"; $escaped_value = mysql_real_escape_string($value); mysql_query("INSERT INTO table (column, column2) VALUES ('{$escaped_value}', "0")"); 

When I check the data in the database, they look the same as in $ value, so "It Time" and not "It\ Time" . This is normal? Shouldn't this add a slash before the quotation marks?

+7
source share
3 answers

This is the correct behavior, and it works! Quotation marks are escaped in the query, not in the database. \ 'in the SQL query must be converted to' inside the database.

You avoid strings, so the SQL query does not get corrupted and allows you to enter quotation marks into the database without the SQL query interpreting them as control characters.

Your screened request will be:

 mysql_query("INSERT INTO table (column, column2) VALUES ('It\ time', "0")"); 

Your database data should be "This time."

If this could not be avoided, it would be:

 mysql_query("INSERT INTO table (column, column2) VALUES ('It time', "0")"); 

He will throw out an error regarding β€œtime” (because he will only interpret until the next quotation mark character and will see only β€œThis”.) And β€œThe time has come!” it's just a harmless line, but because of this, many attacks can occur if you do not escape your characters.

+10
source

Short answer

It is right.

Long answer

This is correct, but your question indicates a lack of understanding of what is happening here. Here is your request:

 INSERT INTO table (column, column2) VALUES ('{$escaped_value}', "0") 

Let's see what happens if you do not leave, and the user enters the following data:

 Eve' 

Remember that you just pass the string to MySQL, the insert is done by processing the PHP string. This means that in this case, the query sent by mysql_query is:

 INSERT INTO table (column, column2) VALUES ('Eve'', "0") 

Which is a syntax error and will result in a page error. Now that a user like me (i.e., the Bastard seeking to make your day unhappy: D) notices one of them, we know it's time to play. What happens if the user provides the following data?

 Eve', "0"); DROP TABLE table-- 

Our request has been expanded to:

 INSERT INTO table (column, column2) VALUES ('Eve', "0"); DROP TABLE table--', "0") 

This is not a syntax error, but it is problematic ... now we are executing a query that we never expected! (If you do not recognize it, "-" means a comment in SQL, that is, "ignore everything after this point").

Now this cannot happen in this particular case ( mysql_query does not support multiple queries ), but this is the attack you are trying to prevent - an attack class known as SQL injection . Let's see what happens when you use mysql_real_escape_string!

The entered data becomes:

 Eve\', \"0\"); DROP TABLE table-- 

This means our query string looks like this:

 INSERT INTO table (column, column2) VALUES ('Eve\', \"0\"); DROP TABLE table--}', "0") 

What well! Data entered by the user will be stored in the database as it is entered. Not without quotes and not with additional backslashes, but the way they entered. This is important. If you store data in any other way, later you will have problems with unshielding or double shielding. In addition, the addition of additional slashes or the like often leads users to be open to users anyway, and this is a gigantic warning sign that things cannot be properly shielded. You want to avoid the wrong actions and especially want to avoid the wrong actions and advertising about it, which leads me to the following section:

Alternatives to shielding your data

  1. Magical quotes. As you noticed, it is not recommended (and not without reason) to avoid.
  2. Do not avoid your data. I would advise against this option.
  3. Remove bad characters from input. Annoying in almost all situations, you should store what users enter and not what is technically easy to store.
  4. Prevent bad characters from entering. Sometimes acceptable (credit card number fields should not handle quotes), sometimes annoying, sometimes a massive warning sign (for example, in a password field)
  5. Prepared statements. I said that the "filling" of the variables in the string was done by PHP, and MySQL just got the query string, hence the need for escaping. Prepared statements will offload this work, being a little smarter, and using prepared statements will look something like this (warning: pseudocode):

    $ Statement = $ db-> prepare ('INSERT INTO table (column, column2) VALUES ("% 1", "% 2")'); $ result = $ statement-> execute ($ value1, $ value2);

There is a good question about the stack overflow about SQL escaping methods, and the answers to them go deeper, so you can read about it.

Personally, I like this option. You cannot forget to shield the variable and insert it into the database in this way - either the values ​​are correctly distributed, or they are not near the database, there is no halfway option. That is, if you undertake that all requests go through prepared statements, rather than string concatenation, as

 $db->prepare('INSERT INTO table VALUES('.$value.')')) 

Done. In my opinion, this is easier than tracking which variables are cleared and which are not. Some people like to avoid strings as soon as they come from the user, but it is very embarrassing if they can go anywhere other than the database - back to HTML, to memcache, etc. If you are going to do it yourself, I could suggest some Hungarian notation, for example:

 $uValue = $_POST['value']; $sValue = escape($uValue); $db->query('INSERT INTO table VALUES(' . $sValue .')'); 

I first saw this idea in an excellent article by Joel Spolsky: " Wrong code looks wrong ."

Conclusion

Hope you feel better prepared for building injection sites now. Good luck with any method you choose and have fun by always avoiding user input before it enters the database! ;)

+10
source

mysql_real_escape_string () is usually sufficient to prevent SQL injection .

You should also filter out the numerical values ​​you get from the user (using intval ()).

0
source

All Articles