User Tools

Site Tools


magic_quotes_stripped

Proposal for handling magic_quotes_gpc

The introduction of the magic_quotes_gpc is probably the most loathed “feature” of PHP. PHP tries to be clever by autoescaping quotes and backslashes received from POST and GET data. Unfortunately there is no way to disable this behavior on runtime. Developers can only determine the status of the setting by using get_magic_quotes_gpc. This page makes a proposal to all PHP developers to establish a pseudo standard to make various PHP applications' magic quotes handling compatible by introducing the MAGIC_QUOTES_STRIPPED define.

Current approaches

There are two approaches to deal with the setting a way that is compatible different target servers.

Selective slashadding

magic_quotes_gpc was invented to make inserting posted data into a database simpler, by automatically escaping the quote and backslash characters as used in SQL strings. A often suggested solution is to use a custom escape function like the following when inserting data into a SQL database:

function safeslashes($string){
  if(get_magic_quotes_gpc()){
    return ($string);
  }else{
    return (addslashes($string));
  }
}

The above function relies on PHP's autoescaping when magic_quotes_gpc is enabled and only calls addslashes if not.

Unfortunately this solves the problem only when the data really is meant for insertion into a database. If you want to display the data or save it to a text file you always need a call to stripslashes.

Selective slashstripping

The alternative suggestion is to use a global include file at the very top of every script. In this include stripslashes is applied to the superglobals (like $_POST or $_GET) once when magic_quotes_gpc is enabled. This is a nice method of making sure incoming data is always in the same unescaped state.

However this brings up a problem: As soon as two different applications are using each others libraries (eg. a CMS including a Forum) you suddenly may have the stripping applied twice.

The Proposal: a standard define

The proposal is to agree on a shared standard when using the second of the above mentioned methods. To avoid applying the slash stripping twice the developer should make sure a define with the name MAGIC_QUOTES_STRIPPED is set, announcing the action to other potential libraries coming with their own strip method.

If stripping is done it should always be done in a complete way, meaning to strip all superglobal regardless of which are used later.

Here is a example on how to do this:

if (get_magic_quotes_gpc() && !defined('MAGIC_QUOTES_STRIPPED')) {
  if (!empty($_GET))     remove_magic_quotes($_GET);
  if (!empty($_POST))    remove_magic_quotes($_POST);
  if (!empty($_COOKIE))  remove_magic_quotes($_COOKIE);
  if (!empty($_REQUEST)) remove_magic_quotes($_REQUEST);
 
  define('MAGIC_QUOTES_STRIPPED',1);
}
 
function remove_magic_quotes(&$array) {
  foreach (array_keys($array) as $key) {
    if (is_array($array[$key])) {
      remove_magic_quotes($array[$key]);
    }else {
      $array[$key] = stripslashes($array[$key]);
    }
  }
}

The above code makes sure the effect of magic_quotes_gpc is reverted but is only run when get_magic_quotes_gpc returns true and the MAGIC_QUOTES_STRIPPED wasn't set. After stripping the slashes it set this define it self.

Users who prefer the first one of the methods mentioned above should still check for the MAGIC_QUOTES_STRIPPED define:

function safeslashes($string){
  if(get_magic_quotes_gpc() && !defined('MAGIC_QUOTES_STRIPPED')){
    return ($string);
  }else{
    return (addslashes($string));
  }
}

Benefits and Drawbacks

The proposed solution does not revert the trouble introduced by magic_quotes_gpc but offers a solution which will not break any existing code. However it only offers benefit in the field of integrating various PHP applications. This benefit is only available when all involved applications honor the MAGIC_QUOTES_STRIPPED define.

Application support

Discussion

Suggestions? Comments? Supporter?

magic_quotes_stripped.txt · Last modified: 2006/11/13 13:50 by andi