I recently had the experience of writing a vanilla PHP application for the first time in ages, without the benefit of a CMS or other framework underlying my code. This choice made sense to me, as the app was tiny and highly customized. However, it re-exposed me to many of the jagged edges I've come to forget because they are smoothed over by most frameworks. One of these is PHP's "Magic Quotes" feature. From the PHP manual:
Magic Quotes is a process that automagically escapes incoming data to the PHP script.
This feature was introduced to provide automatic protection against SQL injection attacks by the user of the application. Sounds great, eh? Well, it is until you try to provide your own protections against such attacks. I have become accustomed to sanitizing all parameters to SQL queries before executing them, using code looking something like:
function execute($sql, $parameters = array()) {
$sql_parts = explode('?', $sql);
$sql = array_shift($sql_parts);
foreach ($parameters as $param) {
$sql .= mysql_real_escape_string($param, $this->connection);
$sql .= array_shift($sql_parts);
}
return mysql_query($sql);
}
By making sure that this layer is in place whenever we pass user input into a database query, we can ensure that malicious entries are cleaned up before they are sent to the database. But... PHP's "magic quotes" feature attempts to do this same job, but it happens at the time the GET, POST, or COOKIE data is pulled in from the browser. This means you may see excess backslashes appearing in your application, if user input is echoed to the screen or, say, an e-mail message. Worse yet, if you have already planned to escape strings before sending them to SQL, as we did in the example above, then you could end up with runaway backslashes. For example:
- User enters into a CMS field:
We're going to the store.
- PHP escapes the POST parameter:
We\'re going to the store.
- Our code escapes the string:
We\\\'re going to the store
- MySQL stores:
We\'re going to the store.
So later, when the content is viewed, there is a backslash where there should not be. If the content is then edited and saved, it gets worse:
- User enters into a CMS field:
We\'re going to the store.
- PHP escapes the POST parameter:
We\\\'re going to the store.
- Our code escapes the string:
We\\\\\\\'re going to the store
- MySQL stores:
We\\\'re going to the store.
The backslashes will quickly spiral out of control. The solution? Turn off "magic quotes." Always. In the .htaccess
file for your site, you can write:
php_value magic_quotes_gpc 0
Do all the necessary escaping in your code, and test it. Don't rely on PHP to do this work for you. Note that magic quotes are on by default in some installs, and off in others, and also that PHP6 will (finally!) remove this feature.
Need a fresh perspective on a tough project?
Let’s talk about how RDG can help.