Significance of the backslash? - php

magic_quotes_gpc
We all hate it and many servers still use this setting and knowingly enough some provides will argue it's safer but I must disagree.
The question I have is, what would a backslash be needed for?
I want to remove them completely which I can do but I am not sure if they are needed?
EDIT
Other then SQL injection.

magic_quotes_gpc() was provided based on the misguided notion that ALL data submitted to PHP from any external source would be immediately inserted into a database. If you wanted to send that data somewhere OTHER than a database, you had to remove the slashes that PHP just inserted, doubling the work required.
As well, not all databases use slashes for escaping metacharacters. \' is fine in MySQL, but in MS Access, escaping a single quote is actually '' - so not only was PHP doing unecessary work, in many situations, it was doing the work WRONG to begin with.
And then, on top of all that, addslashes (which is basically what magic_quotes_gpc() was calling internally) can't handle all forms of SQL injection attacks, particularly where Unicode is used. addslashes is a glorified form of str_replace("'", "\\'", $string), which works at the ASCII level - plenty of Unicode sequences can look like regular ascii, but get turned into SQL metacharacters after a simplistic addslashes() has wreaked its havoc.

They are for preventing SQL injection exploits, a very serious issue you should read up on if you're going to be coding for the web.
You should look into prepared queries, which is a much better way of avoiding SQL injection.

There is no good reason to have this feature in PHP.
That's why it's officially deprecated and will not exist in future versions.
If there were good reasons to keep it, the developer community would have done so.

They are designed to make us do extra work to remove them. For example, some code in Dokuwiki.
Don't forget about magic_quotes_runtime too.

Related

Why Magic Quotes has been removed from PHP 5.4?

What are the technical reasons that Magic Quotes has been removed from PHP 5.4 ?
From PHP docs
Performance
Performance Because not every piece of escaped data is inserted into a database, there is a performance loss for escaping all this data. Simply calling on the escaping functions (like addslashes()) at runtime is more efficient. Although php.ini-development enables these directives by default, php.ini-production disables it. This recommendation is mainly due to performance reasons.
Is there any other reason why Magic Quotes has been removed from PHP?
this is very well explained why the deprecated in manual by chao
Quoting comment of chao
The very reason magic quotes are deprecated is that a one-size-fits-all approach to escaping/quoting is wrongheaded and downright dangerous. Different types of content have different special chars and different ways of escaping them, and what works in one tends to have side effects elsewhere. Any sample code, here or anywhere else, that pretends to work like magic quotes --or does a similar conversion for HTML, SQL, or anything else for that matter -- is similarly wrongheaded and similarly dangerous.
Magic quotes are not for security. They never have been. It's a convenience thing -- they exist so a PHP noob can fumble along and eventually write some mysql queries that kinda work, without having to learn about escaping/quoting data properly. They prevent a few accidental syntax errors, as is their job. But they won't stop a malicious and semi-knowledgeable attacker from trashing the PHP noob's database. And that poor noob may never even know how or why his database is now gone, because magic quotes (or his spiffy "i'm gonna escape everything" function) gave him a false sense of security. He never had to learn how to really handle untrusted input.
also good read Wikipedia : Magic quotes Criticism

Will magic_quotes_gpc save me from this?

There is a (ugly)project I was asked to help with by doing a specific task.
The thing is, I don't have any control over the other files in the site much less over the server configuration. Some data I'm going to use comes from a query like this:
'SELECT * FROM table where value like "'.$unsafe.'"';
$unsafe is an unescaped value coming from $_POST or $_GET.
I checked the server, is PHP5.1.6 and has magic_quotes_gpc On so the data is being auto escaped.
Is this query breakable? Being $unsafe between colons gives me the impression It cant be broken but maybe I'm missing something.
I know magic_quotes_gpc is deprecated because of its insecurity so I'm concerned about it, not because of the application security which fails every where but for my own knowledge.
EDIT: I'm aware of the security implications of *magic_quotes_gpc* and I never use it in my own projects. I always use parameterized queries to avoid injection but this time I was asked to add a very specific pice of code in a friend/client project, so I cant change what is already done. I'd like to know if there is a specific value I can use to create an injection so I can illustrate my friend why he should change it.
if the DB is mysql use mysqli_real_escape_string() instead, if the PHP version is very old you can use the mysql_real_escape_string (not recommended at the moment).
even if the variable is between colons it can be injected, you just need to close the colons inside the value of the variable and then inject whatever you want afterwards.
With regard to your edit: You asked "I'd like to know if there is a specific value I can use to create an injection so I can illustrate my friend why he should change it."
According to the manual page for mysqli_real_escape_string(), the characters it escapes are as follows:
NUL (ASCII 0), \n, \r, \, ', ", and Control-Z.
The old mysql_real_escape_string() function also escapes the same characters.
This gives you a starting point as to which characters can be used to do injection attacks in MySQL. Magic quotes only escapes the quote characters and the slash character, which clearly leaves several gaping holes that can be exploited.
In an easy world, the above information would be enough for us to fix the escaping by doing a string replace on the remaining unescaped characters.
However, both the real_escape functions also require an active database connection for them to work, and this leads us to a further complication: character sets.
Further attacks are possible if the database has a different character set to PHP, particularly with variable-length character sets such as UTF-8 or UTF-16.
An attacker who knows (or can guess) the character set that PHP and the DB are using can send a crafted injection attack string that contains characters that PHP would not see as needing escaping, but which would still cause succeed in hacking MySQL. This is why the real_escape functions need to access the DB in order to know how to do the escaping.
Further resources:
Php & Sql Injection - UTF8 POC
SQL injection that gets around mysql_real_escape_string()
I hope that gives you a few pointers.

PHP Delimiting Quotation marks

I'm working on a PHP comment system and came across the problem that the commentator's quotation marks are delimited when written to the comment file, so the output would end up like this for example:
"That is your father\'s! It\'s special to him!" (random sentence). How do I disable this?
The backslashes are added to the database query to prevent SQL injection. You can use the stripslashes() function to remove them when you retrieve the comments from the database.
You should also take a look at magic quotes.
It depends on version of PHP and it's configuration. Older versions (older than 5.3) had this enabled by default. It adds the quotes when you post your comment (so it will be stored in the database with the quotes). You can disable this behavior:
http://cz.php.net/manual/en/function.get-magic-quotes-gpc.php
http://cz.php.net/manual/en/function.set-magic-quotes-runtime.php
http://cz.php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc
For existing comments, you'll have to run some cleanup script that will fetch all rows, performs stripslashes() on it and save it back.
Escaping your queries should be done by mysql_real_escape() anyway, relying on magic quotes is suicide, so if you think about it, it's safer to turn them off completely and escape the queries manually.
Turn gpc_magic_quote 's off in your php.ini .
Those backslashes are there to escape the quotation marks from the SQL engine.
That style of programming is quite common with the mysql_* series of functions which take a string directly from the program and execute it directly in the database engine. This is notoriously prone to SQL injection attacks and, as you've discovered, corrupting your data. (When applied consistently, you can always de-corrupt the data on the way back to the user, with the stripslashes() function, but that also must be done consistently.)
The far better approach in my humble opinion is to use prepared statements and let the database libraries insert data directly into the database without any escaping or un-escaping involved. This also completely removes the risk of SQL injection attacks. (Though you're still free to write insecure code.)

Do I really need to use mysql_real_escape_string when I save data in the DB?

I am using mysql_real_escape_string to save content in my mySQL database. The content I save is HTML through a form. I delete and re-upload the PHP file that writes in DB when I need it.
To display correctly my HTML input I use stripslashes()
In other case, when I insert it without mysql_real_escape_string, I do not use stripslashes() on the output.
What is your opinion? Does stripslashes affect performance badly ?
Do not use stripslashes(). It is utterly useless in terms of security, and there's no added benefit. This practice came from the dark ages of "magic quotes", a thing of the past that has been eliminated in the next PHP version.
Instead, only filter input:
string: mysql_real_escape_string($data)
integers: (int)$data
floats: (float)$data
boolean: isset($data) && $data
The output is a different matter. If you are storing HTML, you need to filter HTML against javascript.
Edit: If you have to do stripslashes() for the output to look correctly, than most probably you have magic quotes turned on. Some CMS even made the grave mistake to do their own magic quotes (eg: Wordpress). Always filter as I advised above, turn off magic quotes, and you should be fine.
Do not think about performance, think about security. Use mysql_real_escape_string everytime you're inserting data into DB
No, don't escape it. Use prepared statements instead. Store your data in its raw format, and process it as necessary for display - for example, use a suitable method to prevent Javascript from executing when displaying user supplied HTML.
See Bill Karwin's Sql Injection Myths and Fallacies talk and slides for more information on this subject.
See HTML Purifier and htmlspecialchars for a couple of approaches to filter your HTML for output.
Check out a database abstraction library that does all this and more for you automatically, such as ADOdb at http://adodb.sourceforge.net/
It addresses a lot of the concerns others have brought up such as security / parameterization. I doubt any performance saved is worth the developer hassle to do all this manually every query, or the security practices sacrificed.
It is always best to scrub your data for potential malicious or overlooked special characters which might throw errors or corrupt your database.
Per PHP docs, it even says "If this function is not used to escape data, the query is vulnerable to SQL Injection Attacks."

PHP Magic Quotes Question

I've never programmed in an environment with magic quotes turned on before. Now I'm working on a project where it is. This is how I've been setting up user accepted data situations:
$first_name = $_POST['first_name']
if(!get_magic_quotes_gpc()) {
$first_name = mysql_real_escape_string($first_name);
}
With that filtering, am I still open for SQL injection attacks when magic quotes is enabled?
I'm really only concerned about any kind of SQL injection that will break my queries... Other whitelisting, htmlspecialchar() -ing etc. is in place for other areas.
Looking at some similar SO questions it seems that it's being advised to instead check for magic quotes, run 'stripslashes' on the data if it IS turned on, and then always run the escape function. I'm a little apprehensive to do it this way though because all of the existing code in the site assumes it's on.
Thanks!
Working with a legacy system can be a real PITA - especially with something like PHP which let some pretty egregious insecure code be written in the bad old days.
I think you've actually already answered part of your question:
Looking at some similar SO questions it seems that it's being advised to instead check for magic quotes, run 'stripslashes' on the data if it IS turned on, and then always run the escape function. I'm a little apprehensive to do it this way though because all of the existing code in the site assumes it's on.
I would also try and initiate a code review - find all places where use data is being written or used in database queries, and then replace with the more secure escaping. Eventually, you'll replace all of those squirrelly queries, and be able to turn magic quotes off for good.
If you use mysql_real_escape_string (correctly) there is no risk of SQL injection. That doesn't mean the input will be ok. If your magic quotes settings or any other stuff is set incorrectly, your variable may contain an incorrect value. It is still safe however.

Categories