...

View Full Version : Escaping Strings Question



xxkylexx
07-17-2008, 07:08 AM
Hey guys,
I have created a basic little news application for a website I run. I understand that I need to properly escape the string before inserting it into the database by using functions such as mysql_real_escape_string().

Now when I output the data from my database that has any quotes in it, it's going to end up having slashes and all in front of them.

Do I need to just do a simple stripslashes() on all of the data I am getting from the database each time or something? Is this the proper way of doing it?

------------------

Example:
Input for news title is: This is Kyle's News Post

This gets stored in db as: This is Kyle\'s News Post



If I echo out this table row, I end up displaying on my website: This is Kyle\'s News Post

I want to display: This is Kyle's News Post




I guess what I am asking is, what is the proper way of escaping the data for inserting strings into a database, and then what is the proper way of displaying this data back from the database onto my website so I don't end up with problems as described in the example above.


Thanks a lot guys,
Kyle

CFMaBiSmAd
07-17-2008, 07:28 AM
Slashes in data retrieved from a database are the result of the magic_quotes_runtime setting. The slashes are not actually in the database.

Because the magic_quotes_runtime setting has been removed in upcoming php6, it is better to turn the setting off rather than to write code to deal with the slashes that the setting adds.

Fou-Lu
07-17-2008, 07:33 AM
Hi mate,
The escape sequence on database fetched values is from the magic_quotes_runtime. The escape string function preps the data to insert into the database, but does not actually contain those characters - its an indication that the database should keep within the bounds of the already quoted string from the actual query.

I would recommend disabling the runtime with set_magic_quotes_runtime(0). This is defaulted to off in php, but will also be removed in PHP 6. Save yourself a headache and just disable it at all times.


Bah, beaten by CFMaBiSmAd! Thats twice today :P

xxkylexx
07-17-2008, 07:55 AM
Hey guys,
magic_quotes_runtime is already turned off on my server. This can be seen by viewing my PHP info (http://websolvents.com/info.php) file.

I also verified this by running the following, which returned 0.

echo get_magic_quotes_runtime();





The way I am currently storing and retrieving the data is by the following:

variable that gets inserted into the database:

$title = mysql_real_escape_string($_POST['title']);

when printing out the data to my website from the database:

echo $row['title'];

This is resulting the the problem described in the example in my original post. I looked in my database, and the fields do indeed have the escaping slashes stored.

CFMaBiSmAd
07-17-2008, 08:23 AM
That means that the $_POST data is being escaped by the magic_quotes_gpc setting. Your call to mysql_real_escape_string() is double-escaping the data.

The magic_quotes_gpc setting has also been removed in php6. It is best to turn it off than to write code to remove the slashes that it adds to external data.

Fou-Lu
07-17-2008, 08:30 AM
Thats right, I'm so looking forward to this upgrade :D
I've posted some code in the snippets section as well under GPC Stripping Tutorial. That takes care of stripping the slashes from magic_quotes_gpc off of you're globals so you can use mysql_real_escape_string on them. Just throw it in a global file and include it in - you'll be good to go :thumbsup:

xxkylexx
07-17-2008, 05:15 PM
This is annoying. I can't seem to get it turned off properly or something. I turned it all off in my server's php.ini file altogether. You can see this in my PHP Info (http://www.starcraftzone.com/info.php) file. However, I am still continuing to have the same issue.


magic_quotes_gpc Off Off
magic_quotes_runtime Off Off
magic_quotes_sybase Off Off

If I escape my variables in the following manner, I don't end up with the issue:

$content = mysql_real_escape_string(stripslashes($_POST['content']));


Also, can you explain to me how mysql_real_escape_string actually works, and is safe, if it is not escaping the string with slashes? My understanding was it worked just like I assume magic_quotes would on a string.

Thanks again guys.

CFMaBiSmAd
07-17-2008, 05:31 PM
Sometimes, incorrect syntax in the setting will cause the value to display one thing in phpinfo() but cause a different value to be used by php. Show the actual lines where you have set the values.

Are you doing all this work in a single folder? Do you have any .htaccess files that could be modifying the magic_quotes values?

The mysql_real_escape_string() function escapes all the special characters that can break a query. The magic_quote settings and addslashes only escape a small set of special characters, leaving open the possibility that a hacker can insert characters into a query that will cause it to fail and trigger error messages (depending on your server settings and what your code is doing) that could expose information about your server that he should not be able to get.

xxkylexx
07-17-2008, 05:40 PM
Here's my php.ini file:



; This directive is deprecated. Use variables_order instead.
gpc_order = "GPC"

; Magic quotes
;

; Magic quotes for incoming GET/POST/Cookie data.
magic_quotes_gpc = Off

; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
magic_quotes_runtime = Off

; Use Sybase-style magic quotes (escape ' with '' instead of \').
magic_quotes_sybase = Off


I have PHP running in CGI mode, so flags cannot be set in my .htaccess files to overwrite anything from php.ini.

So how does mysql_real_escape_string() escape these characters without inserting a slash, like the others?

Thanks!

CFMaBiSmAd
07-17-2008, 05:54 PM
It does insert a slash (Edit: into the string, not the database.) Echo something after mysql_real_escape_string() has been applied to it.

xxkylexx
07-17-2008, 06:16 PM
Bah. Now I am getting really confused.

Then how am I able to do the following without getting the same results with the slashes echoed back?

--------

Title input: Kyle's News Post


$title = mysql_real_escape_string($_POST['title']);

...

$title inserted into database



...

echo $row['title'];

Displayed on my website from database call: Kyle\'s News Post

I want: Kyle's News Post (but safely stored in my database)

abduraooft
07-17-2008, 06:21 PM
Before displaying the string, pass your data through stripslashes() (http://php.net/stripslashes)

_Aerospace_Eng_
07-17-2008, 06:45 PM
Before displaying the string, pass your data through stripslashes() (http://php.net/stripslashes)

You shouldn't have to if the data isn't escaped twice.

@xxkylexx Are you sure your host allows for a custom php.ini file? Are you by chance hosting the site on your own computer? If so what setup do you have?

xxkylexx
07-17-2008, 06:57 PM
You shouldn't have to if the data isn't escaped twice.

@xxkylexx Are you sure your host allows for a custom php.ini file? Are you by chance hosting the site on your own computer? If so what setup do you have?

I own my server, so I am the host. The above php.ini snippet is taken from the global server php.ini file at /usr/local/lib/php.ini, which I edited.

If I run the string through the following:


$title = mysql_real_escape_string(stripslashes($_POST['title']));

or


$title = $_POST['title'];

or


$title = addslashes(stripslashes($_POST['title']));

The data gets stored in the database as: Kyle's News Post







But if I run the string through this:


$title = mysql_real_escape_string($_POST['title']);

or this:




$title = $_['title'];

if (get_magic_quotes_gpc()) {
$title = stripslashes($title);
}

$title = mysql_real_escape_string($title);



It gets stored into the database as: Kyle\'s News Post

Fou-Lu
07-17-2008, 07:06 PM
This is strange.
I noticed that you're php is compiled with magic-quotes and running as a cgi. I wonder if perchance its still overriding you're configuration directives, but that doesn't explain why get_magic_quotes_gpc() returns false. That last block of code with the gpc check should work for you without any trouble (of course, you meant $_POST['title']).
The simplest test I can think of is a simple form with entry:


<?php

if (isset($_POST['name']))
{
printf("Entered %s<br />\n", $_POST['name']);
if (get_magic_quotes_gpc())
{
print("BTW, GPC is enabled...<br />\n");
}
}
?>
<form method="post">
<input type="text" name="name" />
<input type="submit" value="submit" />
</form>

If you enter Kyle's in there and it show up as Kyle\'s, its definitely you're magic_quotes. If that is the case, the btw message should be displayed. If it doesn't there is something wrong.

xxkylexx
07-17-2008, 07:17 PM
Ran the following code:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
</head>

<body>

<?php

if (isset($_POST['name']))
{
printf("Entered &#37;s<br />\n", $_POST['name']);
if (get_magic_quotes_gpc())
{
print("BTW, GPC is enabled...<br />\n");
}
}
?>

<form method="post">
<input type="text" name="name" />
<input type="submit" value="submit" />
</form>


</body>
</html>




Input: Kyle's


Returned: Entered Kyle's

No BTW message was returned.



:confused::confused::confused::confused:

xxkylexx
07-17-2008, 07:42 PM
I think I have found the problem. I am including a SMF Forums SSI.php file at the top of all my pages which allows me to integrate functions of my site with my forums. I removed this include, and it seems to be working properly:


$title = mysql_real_escape_string($_POST['title']);

now inserts into the database: Kyle's News Post


Now to figure out how this include is enabling magic quotes on the fly, but still not showing up when echoing out get_magic_quotes_runtime();

Fou-Lu
07-17-2008, 07:48 PM
Sometimes its the little things that really catch you!
Chances are the included files are already performing the addslashes or (preferably) mysql_real_escape_string to their own configurations. Doubling these up with you're own calls essentially escaped the escaped values:


$_POST['name'] = "Kyle's";
$name = mysql_real_escape_string($_POST['name']); // Creates Kyle\'s
$name = mysql_real_escape_string($name); // Creates Kyle\\\'s.

So when you are inserting it into the database, it treats the '\' as a literal character - one \ to escape the \ character, followed by \' to escape the '.

Glad you got it working though, these things are such a pain and can set you way back >.<


Didn't notice you're last part there.
Check into the snippet I made for stripping the gpc data. They are likely using a similar technique to perform their escaping. This method IMO is not a very wise one since it does destroy the ability for the developer to control it. I would much rather run a $storage->clean command (on a custom created object for storage) than cross my fingers and hope that another script is controlling it.

xxkylexx
07-17-2008, 07:52 PM
I'm still curious as to how this mysql_real_escape_string() function works.



$_POST['name'] = "Kyle's";
$name = mysql_real_escape_string($_POST['name']);

echo $name; // prints Kyle\'s


but if I insert $name into the database, it is stored as: Kyle's

:confused::confused::confused:

Fou-Lu
07-17-2008, 08:01 PM
You see, the purpose of escaping is to stop a malicious query to be injected into you're query.

The PHP site actually has some good examples of where injections come into play: http://ca3.php.net/manual/en/security.database.sql-injection.php
The idea of cleaning you're data is simply to stop users from breaking out of you're intended query and executing their own. The database itself treats it inside you're query as an escaping character and not as a literal, which is why you need \' to say 'escape this quote and hold the quote'. If you want to actually have it stored as \', you need to generate it with \\\' (escape this slash and store the slash, escape this quote and store the quote).

xxkylexx
07-17-2008, 08:17 PM
Cool. So the quotes (and other possible malicious characters) are escaped with a slash, it is just not stored as a literal slash in the database, so you're data doesn't then get screwed up with all these unwanted slashes everywhere. I was always under the impression that it escaped and stored with literal slashes. Think I got it now.

Thanks for the clarification. You guys always pull through when I get stuck :) .

Fou-Lu
07-17-2008, 08:19 PM
NP mate, thats why they keep us around :thumbsup:



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum