Magic quotes in PHP

According to the PHP manual , in order to make the code more portable, they recommend using something like the following to escape data:

if (!get_magic_quotes_gpc()) { $lastname = addslashes($_POST['lastname']); } else { $lastname = $_POST['lastname']; } 

I have other validation checks that I will perform, but how safe is it strictly in terms of getting out of the data? I also saw that magic quotes will deprecate in PHP 6. How will this affect the above code? I would prefer not to rely on a database-specific escaping function like mysql_real_escape_string ().

+16
security php magic-quotes
Oct 21 '08 at 0:50
source share
12 answers

Magical quotes are inherently broken. They were intended to disinfect input to a PHP script, but without knowing how this input will be used, it is impossible to properly disinfect. Anyway, you better check to see if the magic quotes are included, then call stripslashes () on $ _GET / $ _ POST / $ _ COOKIES / $ _ REQUEST, and then sanitize the variables at the point where you use them somewhere. For example, urlencode () if you use it in a URL, htmlentities () if you print it back to a web page, or use the database driver escaping function if you save it to the database. Note that these input arrays may contain nested arrays, so you may need to write a function that can return to nested arrays to remove these slashes as well.

PHP 's magic quotes man page agrees:

"This function has been DEPRECATED with PHP 5.3.0 and REDACTED with PHP 5.4.0. Using this function is highly undesirable. Magic Quotes is a process that automatically escapes incoming data into a PHP script. It is preferable to encode using magic to disable quotation marks and to escape data instead at runtime as needed. "

+25
Oct 21 '08 at 0:57
source share

The magic quotes were a design mistake. Their use is incompatible with maintaining your sanity.

I prefer:

 if (get_magic_quotes_gpc()) { throw new Exception("Turn magic quotes off now!"); } 

Do not write code for compatibility with malformed settings. Instead, protect their use by specifying your FAIL FAST code.

+17
Oct 21 '08 at 8:43
source share

I use the following code in the header file of my website to undo the effects of magic_quotes:

 <?php // Strips slashes recursively only up to 3 levels to prevent attackers from // causing a Qaru error. function stripslashes_array(&$array, $iterations=0) { if ($iterations < 3) { foreach ($array as $key => $value) { if (is_array($value)) { stripslashes_array($array[$key], $iterations + 1); } else { $array[$key] = stripslashes($array[$key]); } } } } if (get_magic_quotes_gpc()) { stripslashes_array($_GET); stripslashes_array($_POST); stripslashes_array($_COOKIE); } ?> 

Then I can write the rest of my code as if magic_quotes never existed.

+6
Oct 21 '08 at 1:29
source share

"I would rather not rely on the escaping function for a particular database such as mysql_real_escape_string ()"

Then use something like PDO . But you still have to undo the damage done by the magic quotes.

+2
Oct 21 '08 at 8:29
source share

Put a requirement of PHP 5.2 or higher in your code and use the API filter . The filter_* functions directly process raw input data (they never touch $_POST , etc.), so they are not affected by magic_quotes_gpc .

Then this example:

 if (!get_magic_quotes_gpc()) { $lastname = addslashes($_POST['lastname']); } else { $lastname = $_POST['lastname']; } 

May become the following:

 $lastname = filter_input(INPUT_POST, 'lastname'); 
+2
Jan 14 '09 at 3:16
source share

That's right, this is not the best way to do this, and not the safest. An escape is best done in relation to what you slip away. If it is stored in the mysql database, use mysql_real_escape_string, which takes into account other locales, character sets. For HTML, htmlentities. For use in escapeshellcmd code, escapeshellarg. Yes, you probably need to click on the mixers first if magic quotes are included. But it’s better not to count on it or use it.

+1
Oct 21 '08 at 1:00
source share

Regarding the use of a database-specific escaping function, you pretty much need to. I found just using addslashes() to fail in rare cases with MySQL. You can write an escape function that determines which DB you are using, and then use the approriate escape function.

0
Oct 21 '08 at 6:47
source share

You can try the following:

 if (get_magic_quotes_gpc()) { $_REQUEST = array_map('stripslashes', $_REQUEST); $_GET = array_map('stripslashes', $_GET); $_POST = array_map('stripslashes', $_POST); $_GET = array_map('stripslashes', $_COOKIES); } 
0
Nov 28 '08 at 11:21
source share

"I would rather not rely on the escaping function for a particular database such as mysql_real_escape_string ()"

Also addlashes can be fooled as well as check out this post:

http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

0
Jan 14 '09 at 2:41
source share

Your sample code is reverse, you should do the following:

 if (get_magic_quotes_gpc()) { $lastname = stripslashes($_POST['lastname']); } else { $lastname = $_POST['lastname']; } 

Note that this leaves your input in a raw state exactly the same as the user typed it - no additional backslashes and potentially loaded SQL Injection and XSRF attacks - and this is exactly what you want. Then make sure you always use one of the following:

  • When echo enter the variable in HTML, wrap it in htmlentities()
  • When placing in mysql, use prepared statements or else mysql_real_escape_string() as a minimum.
  • When echo enter the variable in Javascritpt code, use json_encode()

Joel Spolsky has good advice on getting started in Incorrect code for the wrong code

0
Jan 14 '09 at 3:42
source share

Just found this in the PHP manual pages , it looks like a pretty smart way to separate them (deals with keys and values) ..):

 if (get_magic_quotes_gpc()) { $_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true); $_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true); $_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true); $_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true); ini_set('magic_quotes_gpc', 0); } 
0
Apr 22 '10 at 6:05
source share

Prepared PDO and Mysqli statements are the best way to prevent SQL injection.

But if you transfer legacy Magic Quotes-based code for each SQL query, you can reference yidas / php-magic-quotes to implement Magic Quotes in an environment with PHP 5.4 above.

https://github.com/yidas/php-magic-quotes

0
Jul 04 '17 at 9:25
source share



All Articles