The (non)sense of PHP "magic quotes"
Thursday, 30 Oct 2008This article will discuss the headache-giving "magic quotes" feature of PHP, which will be removed in PHP 6. I will highlight the idea behind it, explain how it exactly works, the problems it creates for developers, and finally: how to get rid of magic quotes altogether.
"Magic Quotes is a process that automagically escapes incoming data to the PHP script. It's preferred to code with magic quotes off and to instead escape the data at runtime, as needed."
Basically, depending on the magic quotes mode, it will escape incoming data in PHP scripts. The three modes are:
I will focus on the effect of the troublemaker magic_quotes_gpc in this article. Its effect will be that all your $_GET, $_POST, and $_COOKIE variables are automatically slashed (addslashes()). So, if someone posts
Or turn things around: your test server has it disabled, but your production server has it enabled... You end up with lots of \"nice little\\ slashes\" in your contents. Great.
And notice how the database-escape function actually used is addslashes()? Unfortunately this can not guarantee safe escaping, since (depending on your database) you might require a different escape function! Just take your time and think about why there is a monster like magic_quotes_sybase in PHP in the first place (!)
Don't
You could turn it off on your server - however, your code will remain server-configuration dependent. This is very bad.
Rather not
You could wait for PHP6, which eliminates magic quotes from PHP.
Yes
Write a function that reverts your variable to its original state (regardless of the magic quotes setting).
The Idea
The magic quotes feature in PHP is obviously some sort of emergency safety feature for inexperienced programmers. It was implemented in PHP in an attempt to make websites and applications developed by inexperienced programmers to some degree "less vulnerable". Let's just say, PHP had noob-protection-mode implemented and turned on by default. PHP's documentation website states:"Magic Quotes is a process that automagically escapes incoming data to the PHP script. It's preferred to code with magic quotes off and to instead escape the data at runtime, as needed."
Basically, depending on the magic quotes mode, it will escape incoming data in PHP scripts. The three modes are:
- magic_quotes_gpc
affects HTTP Request data (GET, POST, and COOKIE). Cannot be set at runtime, and defaults to on in PHP.
- magic_quotes_runtime
if enabled, most functions that return data from an external source, including databases and text files, will have quotes escaped with a backslash - can be set at runtime, and defaults to off in PHP.
- magic_quotes_sybase
if enabled, a single-quote is escaped with a single-quote instead of a backslash. If on, it completely overrides magic_quotes_gpc. Having both directives enabled means only single quotes are escaped as ''. Double quotes, backslashes and NULL's will remain untouched and unescaped. See also ini_get() for retrieving its value.
What it does
In practice, magic_quotes_gpc will be a trouble-maker, magic_quotes_runtime will be rare (especially since it's turned off by default), and magic_quotes_sybase will be like a pink monkey studying quantum physics (very rare).I will focus on the effect of the troublemaker magic_quotes_gpc in this article. Its effect will be that all your $_GET, $_POST, and $_COOKIE variables are automatically slashed (addslashes()). So, if someone posts
Monkey says: "Hello world".in a form, you will receive it as
Monkey says: \"Hello world\".which, when immediately (without processing) inserted in your database, will be stored correctly (as the magic quotes auto-escape special characters).
Monkey says: "Hello world".Great. If you can't code. It may help a little, but more likely will make things more complex.
The Problems
Now imagine you have your code running on a test-server with magic_quotes_gpc enabled, and everything works great. What happens if you upload this to a server with magic_quotes_gpc disabled? Your script will be completely exposed to SQL-injection.Or turn things around: your test server has it disabled, but your production server has it enabled... You end up with lots of \"nice little\\ slashes\" in your contents. Great.
And notice how the database-escape function actually used is addslashes()? Unfortunately this can not guarantee safe escaping, since (depending on your database) you might require a different escape function! Just take your time and think about why there is a monster like magic_quotes_sybase in PHP in the first place (!)
Solving your "magic quotes" issue
Solving your issues on the subject is fortunately really easy.Don't
You could turn it off on your server - however, your code will remain server-configuration dependent. This is very bad.
Rather not
You could wait for PHP6, which eliminates magic quotes from PHP.
Yes
Write a function that reverts your variable to its original state (regardless of the magic quotes setting).
function mq_kill($value) {
return get_magic_quotes_gpc() ? stripslashes($value) : $value;
}
Or you could just wrap mysql_real_escape_string() (depending on your database) immediately around that to make a truly safe database-escape function for your input variables.


Comments (1)