I have to escape some inputs on a form. I used mysql_real_escape_string to escape the value but it adds a lot slashes with value inside database, the reason is i have an apostrophe in my input let us say exp's.
Now to get rid of slashes, I use stripslashes after mysql_real_escape_string and then data goes to database successfully and don't see any apostrophe with value in database.
$name = mysql_real_escape_string(trim($_POST['userame']));
$name = stripslashes(stripslashes($userame));
// then data goes to db successfully without apostrophe
I just wanted to confirm, is this correct way of escaping the input value? Thanks
Dayan
Disabling Magic Quotes
mysql_real_escape_string(stripslashes($_POST['username']));
No it's not. Check your php.ini for the magic_quotes_gpc setting. If you can't disable it use stripslashes BEFORE using mysql_real_escape_string. The link has a method to strip it globally from $_POST, $_GET and $_COOKIE. Or even better, use prepared statements with PDO
If you have magic_quotes_gpc enabled you should use the stripslashes() function before escaping - otherwise you will escape twice, thus loads of slashes.
http://se.php.net/manual/en/function.mysql-real-escape-string.php
Related
I am having following php string: "Device/ mo\bile's";
I want to insert it into db and so before insert i am sanitizing it with addslashes function
and sanitization happens but the string is inserted into the db as "Device/ mobile's" ie. backlash vanishes.
I want to retain '\' also.
Anybody suggest how can i do that.
Thanks in advance.
Don't use addslashes for escaping SQL. In fact, don't use addslashes for anything. If you are still using the by now deprecated mysql_* functions, use mysql_real_escape_string. If you're using the newer mysqli_* or PDO extension, use prepared statements. Then all data will be inserted properly. If you use unrelated escaping functions which do not consider to appropriate escaping rules for the language at hand, you won't get the correct results.
Currently I use this strategy:
After submitting a HTML form or data sent using jQuery's $.get() or $.post() I need to know what is come and then apply logic on the basis of that.
suppose, I've got $_POST['username'], $_POST['password'] and $_POST['login_submit_button'].
In my processing script file, I do like this:
if(isset($_POST['login_submit_button']) && isset($_POST['username']) && $_POST['username'] != "" && isset($_POST['password']) && $_POST['password'] != "") {
// calling a common function safe_vars() which does
// mysql_real_escape_string(stripslashes(trim($any_variable_need_to_become_safe)))
// and now using the above variables for different purposes like
// calculation, insertion/updating old values in database etc.
}
I know all this logic is wrong or having serious issues, so I want a much-secure and perfect solution instead of this. I welcome to find out vulnerabilities and severe security-bleaches in my strategy. This question can help others too, if answers came more explanatory, this can be informative community wiki.
There is no way to make a generic super "make things safe" function.
mysql_real_escape_string
You shouldn't use this at all. It uses the old mysql API, and assumes you are going to be manually smashing strings together to make SQL. Don't do that. Use PDO or mysqli and a function that deals in prepared queries and bound arguments.
stripslashes
This is an antidote to magic quotes. If magic quotes are not on it will destroy data. Don't use it. Turn magic quotes off instead.
trim
This destroys data. Don't use it unless you really want to remove white space at the start and end of the string.
Escape data for the target language immediately before inserting data into that language.
For SQL, use bound arguments and prepared queries.
For HTML, use htmlspecialchars or a template language that does escaping for you, such as mustache.
Alternatively, (if you want to allow HTML) parse it, generate a DOM, filter it using a whitelist, then serialise it back to HTML.
For JSON, use encode_json
etc.
You only need to stripslashes if you have magic_quotes enabled (use get_magic_quotes_gpc to check)
You should white list filter your POST vars using filter_var or ctype_* or preg_match (as well as checking bound conditions such as length and presence)
Use prepared statements / PDO for your queries to ensure proper escaping
Escape any html output with htmlentities
Nothing is bullet proof, however the above are good practices to avoid SQL injection / XSS.
I'm using following function to protect my db from injection attacks and etc. for gets.
function filter($data) {
global $db;
$data = trim(htmlentities(strip_tags($data)));
if (get_magic_quotes_gpc())
$data = stripslashes($data);
$data = $db->real_escape_string($data);
return $data;
}
foreach($_GET as $key => $value) {
$data[$key] = filter($value);
}
Question is, i want to filter not only $_GET but $_POST too. How to do that?
And can I reassign value to $_GET or $_POST after filtering? I mean $_GET[$key] = filter($value); instead of $data[$key] = filter($value);..
Don't pre-escape your variables, escape them only at the time you need to escape them.
If you prematurely escape your variable, you'll never know which variable is escaped, and which is not
You'll have to unescape your variables before doing string manipulations, and re-escape them after
Variables coming from different sources (like from an API, from a file or even from your database) won't be escaped. You'll forget to escape them.
You'll have to un-escape all your variables before printing them (you don't want to print the \', I guess)
You can't escape a variable for every possible situation. What about escaping them with escapeshellcmd too ?
PHP did this in the past. It was called magic_quotes_gpc.
But it's so bad practice that it's now deprecated, and it will be removed from the next version of PHP.
It's better to just escape everything at the time you need to. You print a variable ? escape it. You don't have to remember if it's already escaped or not: it's not.
this function makes no sense.
and it doesn't filter anything.
and shouldn't be used this way.
to protect your db from injection attacks you shouldn't do most of the things present in this function and should do many things not present there.
to protect only strings (data chunks enclosed in quotes) from injection attacks you have to use $db->real_escape_string and nothing else.
to protect other query parts you have to use other procedures, as real_escape_string become utterly useless for them
to protect your app from "etc attacks" you have to define what is this "etc" first.
array_walk($_GET,'filter');
array_walk($_POST,'filter');
array_walk($_COOKIE,'filter');
You should probably filter the $key too in case you use it in the query later, but if possible you should use mysql prepared statements and bind variables.
http://www.ultramegatech.com/blog/2009/07/using-mysql-prepared-statements-in-php/
You can change $_GET and $_POST.
What is the best way to avoid \' while we get the values from PHP post method and want to store in the database. I have used simply , echo $_POST['txtname'];
it produces the output Uncl\'es Jules, if enter name as Uncl'es Jules
Can any one suggest the better way?
This sounds like you have magic_quotes enabled that's why it is escaping data automagically.
You should disable magic_quotes. Here is how you can
Escape data with mysql_real_escape_string() while inserting them
If magic_quotes is not disabled with any reason you can use stripslashes do remove those extra \.
echo stripslashes($data);
http://php.net/manual/en/function.mysql-real-escape-string.php
use mysql_real_escape_string
Try using mysql_real_escape_string().
insert into tblTable1 set field1 = mysql_real_escape_string($_POST['txtname']);
Or mysqli_real_escape_string(), also PDO has matching functions too.
It is escaping unsafe characters to store in the database. You actually want your SQL library to do this. If you do not do this, you are open to SQL Injection, and that's bad. :)
But it seems like you have magic quotes enabled. Do not use that and use mysql_real_escape_string() to escape your data before it is inserted into the database.
What you need to do is revert all escaped characters back when you display your data.
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.