I'm trying to figure out why this function does not work correctly.
It's adding an extra \ every time I edit my entries.
Online server has these settings:
magic_quotes_gpc On
magic_quotes_runtime Off
magic_quotes_sybase Off
Here is the code:
function esc($s)
{
if (get_magic_quotes_gpc()) {
if (ini_get('magic_quotes_sybase'))
$s = str_replace("''", "'", $s);
else
$s = stripslashes($s);
} //if
return mysql_real_escape_string($s);
}
Edit note:
I have tried completely removing this function to see what it does... and it does the same thing, so I have realized that addslashes is also use in the code for the same thing.
The extra \ were there because magic_quote was ON
Your function makes little sense. If magic quotes is on (eg. input is escaped), you unescape it. If it's not on, you escape it. So you'll get different results, depending on if you have magic quote on or not.
In any case, relying on magic quotes is a really bad practice. You should:
Disable magic quotes or reverse its effect globally.
Either escape strings when you construct SQL queries or (better) use prepared statements.
Not unescape/strip/whatever anything when you get it back from the database.
You probably want to stripslashes even if magic_quotes_sybase is on:
function esc($s)
{
if (get_magic_quotes_gpc()) {
if (ini_get('magic_quotes_sybase'))
$s = str_replace("''", "'", $s);
$s = stripslashes($s);
} //if
return mysql_real_escape_string($s);
}
You might also want to take a look at PHP's get_magic_quotes_gpc function page, there are several user comments on the page with fairly elegant solutions for ensuring slashes are stripped.
Ok I have fixed the problem. A quick solution for now, I have removed function esc($s).
I changed Magic_Quote to OFF in php.ini.
I'm keeping addslashes solution.
Related
I'm no PHP/SQL expert, and I've juste discovered that i had to apply mysql_real_escape_string to secure my SQL INSERTS.
I made a function using several advice found on the net, here it is:
function secure($string)
{
if(is_numeric($string))
{ $string = intval($string); }
elseif (is_array($string))
{
foreach ($string as $key => $value) {
$string[$key] = secure($value);
}
}
else if ($string === null)
{
$string = 'NULL';
}
elseif (is_bool($string))
{
$string = $string ? 1 : 0;
}
else
{
if (get_magic_quotes_gpc()) { $value = stripslashes($string); }
$string = mysql_real_escape_string($string);
$string = addcslashes($string, '%_');
}
return $string;
}
Thing is, when I have a look at my tables content, it contains backslashes.
And then logically, when I retrieve data I have to apply stripslashes to it to remove these backslashes.
Magic Quotes are off.
QUESTION 1)
Now I think that even though I use mysql_real_escape_string to secure my data before SQL insertion, backslashes should not appear in my content ? Can you confirm this ?
QUESTION 2)
If not normal, why are these backslashes appearing in my phpMyAdmin content and retrievals ? What did I did wrong ?
QUESTION 3)
A guess I have is that mysql_real_escape_string could be applied twice, isn't it ?
If so, what could be a function to prevent mysql_real_escape_string being applied many times to a same string, leading to many \\ to a same escapable character ?
Thanks a lot by advance for your inputs guys !
oh, what a senseless function. I know it's not your fault but ones who wrote it in their stupid articles and answers.
Get rid of it and use only mysql_real_escape_string to escape strings.
you have mixed up everything.
first, no magic quotes stuff should be present in the database escaping function.
if you want to get rid of magic quotes, do it centralized, at the very top of ALL your scripts, no matter if they deal with the database or not.
most of checks in this function are useless. is_bool for example. PHP will convert it the same way, no need to write any code for this.
LIKE related escaping is TOTALLY distinct matter, and has nothing to do with safety.
is numeric check is completely useless, as it will help nothing.
Also note that escaping strings has nothing to do with security.
I's just a syntax rule - all strings should be escaped. No matter of it's origin or any other stuff. Just a strict rule: every time you place a string into query, it should be quoted and escaped. (And of course, if you only escape it but not quote, it will help nothing)
And only when we talk of the other parts of query, it comes to the SQL injection issue. To learn complete guide on this matter, refer to my earlier answer: In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?
Your stripslashed $string is stored to the wrong variable $value instead of $string:
if (get_magic_quotes_gpc()) { $value = stripslashes($string); }
should be
if (get_magic_quotes_gpc()) { $string = stripslashes($string); }
Are you sure you aren't calling mysql_real_escape_string more than once, each time you call it with escapable characters you will end up adding more and more slashes. You want to call it only once. Also, why are you also calling addcslashes? mysql_real_escape_string should be enough. If you call it only once, you should never have to call stripslashes on the data after retrieving it from the database.
You can't really tell if mysql_real_escape_string is applied more than once, I'd suggest going back and re-reading your code carefully, try debug printing the values just before they are inserted into the db to see if they are look 'over-slashed'.
Btw, if you are using prepared statements (e.g. via mysqli) you dont need to escape your strings, the DB engine does this for you, this could be the problem too.
Remove addslashes completely from all of your code. This is the leading cause for slashes being inserted into database.
function escape($string) {
if (get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
return mysql_real_escape_string($string);
}
Always check if magic_quotes_gpc is enabled, if it is perform stripslashes and escape the data.
Escaped = "don\'t use addslashes"
When it goes into database the '\' is removed.
Okay my hosting company has magic_quotes_gpc turned ON and I coded my PHP script using stripslashes() in preparation of this. But now the hosting company says its going to turn magic_quotes_gpc OFF and I was wondering what will happen now to my data now when stripslashes() is present should I go through all my millions of lines of code and get rid of stripslashes()? or leave the stripslashes() function alone? will leaving the stripslashes() ruin my data?
Your code should use get_magic_quotes_gpc to see if magic quotes are enabled, and only strip slashes if they are. You should run a block of code similar to the following in exactly one place, shared by all your scripts; if you're using stripslashes in multiple places you're doing it wrong.
// recursively strip slashes from an array
function stripslashes_r($array) {
foreach ($array as $key => $value) {
$array[$key] = is_array($value) ?
stripslashes_r($value) :
stripslashes($value);
}
return $array;
}
if (get_magic_quotes_gpc()) {
$_GET = stripslashes_r($_GET);
$_POST = stripslashes_r($_POST);
$_COOKIE = stripslashes_r($_COOKIE)
$_REQUEST = stripslashes_r($_REQUEST);
}
I would start going through and removing stripslashes(). You can do this ahead of time by testing for magic_quotes_gpc and only calling stripslahes() if it is needed.
meagar has the correct answer.
But to traverse the situation, you need something like Notepad++ with a Search within files function. Copy a snippet of meagar's code and search for stripslashes()
This question already has answers here:
Why are $_POST variables getting escaped in PHP?
(6 answers)
Closed 7 years ago.
I have a php page which contains a form.
Sometimes this page is submitted to itself (like when pics are uploaded).
I wouldn't want users to have to fill in every field again and again, so I use this as a value of a text-input inside the form:
value="<?php echo htmlentities(#$_POST['annonsera_headline'],ENT_COMPAT,'UTF-8');?>">
This works, except it adds a "\" sign before every double-quote...
For instance writing 19" wheels gives after page is submitted to itself:
19\" wheels
And if I don't even use htmlentities then everything after the quotes dissappears.
What is the problem here?
UPDATE:
Okay, so the prob is magic_quotes... This is enabled on my server...
Should I disable it? I have root access and it is my server :)
Whats the harm in disabling it?
Looks like you have magic quotes turned on. Use below condition using stripslashes with whatever text you want to process:
if(get_magic_quotes_gpc())
{
$your_text = stripslashes($your_text);
}
Now you can process $your_text variable normally.
Update:
Magic quotes are exaplained here. For well written code there is normally no harm in disabling it.
You likely have magic quotes turned on. You need to stripslashes() it as well.
Nicest way would be to wrap this in a function:
function get_string($array, $index, $default = null) {
if (isset($array[$index]) && strlen($value = trim($array[$index])) > 0) {
return get_magic_quotes_gpc() ? stripslashes($value) : $value;
} else {
return $default;
}
}
Which you can use as
$annonsera_headline = get_string($_POST, 'annonsera_headline');
By the way:
And if I don't even use htmlentities then everything after the quotes dissappears.
It's actually still there in the HTML source, you only don't see it. Do a View Source ;)
Update as per your update: the magic quotes is there to prevent SQL injection attacks in code of beginners. You see this often in 3rd party hosts. If you really know what you're doing in the code, then you can safely turn it off. But if you want to make your code distributable, then you'll really take this into account when gathering request parameters. For this the above function example is perfectly suitable (you only need to write simliar get_boolean(), get_number(), get_array() functions yourself).
Yes, you should disable magic quotes if you can. The feature is deprecated, and will likely go away completely in the future.
If you've relied on magic quotes for escaping data (for instance when inserting it into a database) you will may be opening yourself up to sql injection vulnerabilities if you disable it. You should check all your queries and make sure you're using mysql_real_escape_string().
I include the following file to undo magic quotes in apps that are deployed to servers not under my control.
<?php
set_magic_quotes_runtime(0);
function _remove_magic_quotes(&$input) {
if(is_array($input)) {
foreach(array_keys($input) as $key) _remove_magic_quotes($input[$key]);
}
else $input = stripslashes($input);
}
if(get_magic_quotes_gpc()) {
_remove_magic_quotes($_REQUEST);
_remove_magic_quotes($_GET);
_remove_magic_quotes($_POST);
_remove_magic_quotes($_COOKIE);
}
return true;
?>
This is actually a function of PHP trying to be security conscious, luckily there is an easy fix for it that looks something like this:
if (get_magic_quotes_gpc()) {$var = stripslashes($var);}
There isn't a huge problem in having it enabled, it comes down to personal preference. If you code will be moving servers much and you can't disable it through your php.ini file, it's best to use something as described above.
If you have access to your php.ini file and you want to change it, because you don't want to have to validate it each time you can add the following line to php.ini
magic_quotes_gpc = Off
Or the following to your .htaccess:
php_flag magic_quotes_gpc Off
Hope this helps clear things up.
Looks like your server is setup to use Magic Quotes.
You can fix it by stripping them with stripslashes, or better, by turning off Magic Quotes.
you shouldn't use htmlentities() when writing something to an input field value.
is magic_quotes enabled on your server? try out stripslashes before the output.
I have a simple PHP script I use to front-end an SQLite database. It's nothing fancy or complex. But I have noticed from looking at the records in the database that anything I enter in a form-field with double-quotes comes across in the form-processing as though I'd escaped the quotes with a backslash. So when I entered a record with the title:
British Light Utility Car 10HP "Tilly"
what shows up in the database is:
British Light Utility Car 10HP \"Tilly\"
I don't know where these are coming from, and what's worse, even using the following preg_replace doesn't seem to remove them:
$name = preg_replace('/\\"/', '"', $_REQUEST['kits_name']);
If I dump out $name, it still bears the unwanted \ characters.
You have most probably magic_quotes_gpc set to on in php.ini. If you want to avoid that and use your own regex, make a check like this:
if (get_magic_quotes_gpc())
{
$mytext = stripslashes($your_text);
}
// and your further code....
This means your server has magic_quotes_gpc enabled.
You can use ini_set() to disable this setting, or you can create a method to filter the $_REQUEST values()
function getRequest($key)
{
$val = $_REQUEST[$key];
if(get_magic_quotes_gpc() == 1) {
$val = stripslashes($val);
}
return $val;
}
echo getRequest('kits_name');
Is it possible magic quotes are enabled on the server?
You probably have magic quotes turned on.
You should disable these as it's bad practice and is deprecated.
View this doc to learn how to disable them.
Well because of lack of good answers.
As they said above, it is because magic quotes on.
You have to get rid of these slashes before inserting your data.
So, to get rid of it you can use either .htaccess (if any) with these settings
php_flag magic_quotes_gpc 0
php_flag magic_quotes_runtime 0
or make it manually, with code like this
if ( get_magic_quotes_gpc( ) ) {
$_GET = array_map_recursive('stripslashes', $_GET) ;
$_POST = array_map_recursive('stripslashes', $_POST) ;
$_COOKIE = array_map_recursive('stripslashes', $_COOKIE) ;
$_REQUEST = array_map_recursive('stripslashes', $_REQUEST) ;
if (isset($_SERVER['PHP_AUTH_USER'])) stripslashes($_SERVER['PHP_AUTH_USER']);
if (isset($_SERVER['PHP_AUTH_PW'])) stripslashes($_SERVER['PHP_AUTH_PW']);
}
if your php version doesn't support array_map_recursive function, you can use a recursive function like this one
function strips(&$el) {
if (is_array($el))
foreach($el as $k=>$v)
strips($el[$k]);
else $el = stripslashes($el);
}
or write your own one
You can use this code co cleanse your existing data
As for
If I dump out $name, it still bears
the unwanted \ characters.
it may be result of wrong use htmlspecialchars function
I just moved to a new hosting company and now whenever a string gets escaped using:
mysql_real_escape_string($str);
the slashes remain in the database. This is the first time I've ever seen this happen so none of my scripts use
stripslashes()
anymore.
This is on a CentOS 4.5 64bit running php 5.2.6 as fastcgi on a lighttpd 1.4 server. I've ensured that all magic_quotes options are off and the mysql client api is 5.0.51a.
I have the same issue on all 6 of my webservers.
Any help would be appreciated.
Thanks.
Edit:
Magic Quotes isn't on. Please don't recommend turning it off. THIS IS NOT THE ISSUE.
The host that you've moved probably has magic_quotes_runtime turned on. You can turn it off with set_magic_quotes_runtime(0).
Please turn off magic_quotes_runtime, and then change your code to use bind variables, rather than using the string escaping.
I can think of a number of things that could cause this. But it depends how you are invoking SQL queries. If you moved to use parameterized queries like with PDO, then escaping is unnecessary which means the call to mysql_real_escape_string is adding the extra slashes.
If you are using mysql_query etc. then there must be some code somewhere like addslashes which is doing this. This could either be before the data is going into the database, or after.
Also you say you have disabled magic quotes... if you haven't already, just do a hard check in the code with something like this:
echo htmlentities($_GET['value']); // or $_POST, whichever is appropriate
Make sure there are no slashes in that value, then also check this:
echo "Magic quotes is " . (get_magic_quotes_gpc() ? "ON" : "OFF");
I know you've said multiple times it isn't magic quotes, but for us guys trying to help we need to be sure you have checked the actual PHP output rather than just changing the config (which might not have worked).
it sounds as though you have magic quotes turned on. Turning it off isn't too hard: just create a file in your root directory called .htaccess and put this line in it:
php_flag magic_quotes off
If that's not possible for whatever reason, or you want to change your application to be able to handle magic quotes, use this technique:
Instead of accessing the request variables directly, use a function instead. That function can then check if magic quotes is on or off and strip out slashes accordingly. Simply running stripslashes() over everything won't work, because you'll get rid of slashes which you actually want.
function getVar($key) {
if (get_magic_quotes_gpc()) {
return stripslashes($_POST[$key]);
} else {
return $_POST[$key];
}
}
$x = getVar('x');
Now that you've got that, all your incoming variables are ready to be escaped again and mysql_real_escape_string() won't stuff them up.
the slashes remain in the database.
It means that your data gets double escaped.
There are 2 possible reasons:
magic quotes are on, despite of your feeling. Double-check it
There is some code in your application, that just mimic magic quotes behaviour, escaping all input.
This is very common misconception to have a general escaping function to "protect" all the incoming data. While it does no good at all, it also responsible for the cases like this.
Of so - just find that function and wipe it out.
You must probably have magic quotes turned on. Figuring out exactly how to turn it off can be quite a headache in PHP. While you can turn off magic quotes with set_magic_quotes_runtime(0), it isn't enough -- Magic quotes has already altered the input data at this point, so you must undo the change. Try with this snippet: http://talks.php.net/show/php-best-practices/26
Or better yet -- Disable magic quotes in php.ini, and any .htaccess files it may be set in.
I am not sure if I understand the issue correctly but I had a very same problem. No matter what I did the slashes were there when the string got escaped. Since I needed the inserted value to be in the exact same format as it was entered I used
htmlentities($inserted_value)
this will leave all inserted quote marks unescaped but harmless.
What might be the problem (it was with us) that you use mysql_real_escape_string() multiple times on the same var. When you use it multiple times, it will add the slashes.
Function below will correctly remove slashes before inserting into the database. I know you said magic quotes isn't on but something is adding slashes so try the following page and see the output. It'll help figure out where. Call with page.php?var=something-with'data_that;will`be|escaped
You will most likely see number three outputting more slashes than needed.
*Change the db details too.
<?php
$db = mysql_connect('host', 'user', 'pass');
$var = $_REQUEST['var'];
echo "1: $var :1<br />";
echo "2: ".stripslashes($var)." :2<br />";
echo "3: ".mysql_real_escape_string($var)." :3<br />";
echo "4: ".quote_smart($var)." :4<br />";
function quote_smart($value)
{
// Stripslashes is gpc on
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// Quote if not a number or a numeric string
if ( !is_numeric($value) )
{
$value = mysql_real_escape_string($value);
}
return $value;
}
?>
mysql_real_escape_string($str); is supposed to do exactly that. it is meant to add backslashes to special characters especially when you want to pass the query to mysql. Take note that it also takes into account the character set of mysql.
For safer coding practices it would be good to edit your code and use stripslashes() to read out the data and remove the slashes.