From a form, I'm asking the user to enter some text. I will retrieve this text using $_POST['text'].
The user enters the string "It's my text!"
$newText = mysql_real_escape_string($_POST['text']);
Now on the very same page after I've inserted $newText into the database I want to display
the text to the user and also use it as the value of an input text box using PHP.
// I want to make sure the user hasn't added any unsafe html in their string
$newText = htmlentities($newText);
echo "You've entered: " . $newText . "<br />";
echo "<form action=someaction.php method=post>";
echo "<input type=text value=\"" . $newText . "\">";
echo "</form>";
The output is:
You've entered: It\'s my text!
[It\'s my text!]
How do I avoid these slashes, and should I be doing anything else with my data?
You're passing the text through mysql_real_escape_string() which, as the name suggests, escapes the string, including apostrophes. mysql_real_escape_string() is meant only for preparing the data for saving to database. You shouldn't use it when displaying data to the user.
So, the solution is simple: remove the line and use htmlentities() only. Use mysql_real_escape_string() when you're saving the string to database (and only then).
Only use mysql_real_escape_string() on the variable you want to use in the query, because it will add slashes to escape some of the characters in the string. This works great for mysql, but when want to use it on the page it will look weird.
You could make 2 variables, 1 for MySQL and 1 for displaying the raw text.
$text = $_POST['text'];
$db_text = mysql_real_escape($text);
Also note that you should use strip_slashes() on the data you get from the database later, to remove the slashes.
Hope this clear things up a little bit.
Now on the very same page after I've inserted $newText into the database I want to display the text to the user
That's what you are doing wrong.
An HTTP standard require a GET method redirect after every successful POST request.
So, you have to redirect the user on the same page, where you may read inserted data from the database and show it to the user.
As for the mistake you made - just move escaping somewhere closer to the database operations, to make sure it is used only for the purpose (YET it is used obligatory, without the risk of forgetting it!).
Ideally you have to use some variables to represent the data in the query, and some handler to process them.
So, the query call may look like
DB::run("UPDATE table SET text=s:text",$_POST['text']);
where s:text is such a variable (called placeholder), which will be substituted with the $_POST['text'] value, properly prepared according to the type set in the placeholder name (s means "string", tells your function to escape and quote the data)
So, all the necessary preparations will be done inside and will spoil no source variable.
save normally using mysql_real_escape_string()
and when you want to display it in a form:
htmlspecialchars(stripslashes($row['text_data']))
it will do the trick.
Related
I want to post data into database in safe mode.
For example if i want to add this title to database:
$title = " here is title 'here is title' here is title ";
notice it has apostrophes.
I use this function to make string safe:
function stringsafe($string)
{
$string = strip_tags(trim(addslashes($string)));
return $string;
}
as you see it's adding slashes before apostrophes to make it safe.
I tried to remove slashes when i show the data by stripslashes, it's working but it's has some problems. Is there anyway to post data into database?
On a side note, in fact the general rules of thumb is that, you shouldn't alter user input at all. You should store whatever user input as it is, into your database, so that you can retain user input as original as possible, and only escape it when you need to display or use it.
In your case, yes you are right you have to prevent it from being injected, but you are altering the original input by adding slashes into the original input, which is not very favoured. What if my title contains a string like this <My 21st Birthday Party!> and you stripped it away?
Try using Prepared Statements instead so you can insert any data into your database, without the worries of injection. And only when you need the data to be displayed on a HTML page or console, you escape them accordingly such as htmlentities.
The code below takes a string protects its using mysqli_real_escape_string.
but not geting expected output working fine without the mysqli_real_escape_string but need that for protection.
$str = mysqli_real_escape_string($con,$_POST['str']);
/*
get each word in the sentence using for-loop then
*/
switch($eachword){
case ':)': $eachword = '<img src="smile.gif">';
break;
/*
and so forth and so on
*/
}
$newstr .= $eachword;
//for-loop ends
**mysqli_query($con,"insert into tbl(comment)VALUES($newstr)");**
e.g
input : $str = "here i am :) fine";
expected output : $newstr="here i am <img src="smile.gif"> fine";
curernt output : $newstr="here i am :) fine";
UPDATE
NOW everything works fine. Thanks to supporters.
You are running mysqli_real_escape_string over some data immediately before … not using at all in your code sample. So it doesn't make any sense.
Use mysqli_real_escape_string immediately before inserting the variable into a string of SQL and nowhere else. (Better yet, use prepared queries and bound arguments).
If you are trying to defend against XSS, then use htmlspecialchars immediately before inserting a variable into a string of HTML.
Don't use either before comparing user input to some text.
UPDATED
Note that you must be already connected to a database, for mysqli_real_escape_string to work, because it takes into consideration, the default character set of your selected database. Are you connecting to a database before using it?
And in your question, I don't even see a query. There will be no advantage in using mysqli_real_escape_string unless you're going to insert the passed string into a database.
Now I see that you're replacing smileys with tag, then you're inserting it into a database. However, if I were you, I would do the following :
function ParseSmiley($str)
{
$smileys = array(
':)' => "<img src='smile.gif' />" //Put all your smileys in this array
);
$parsed_string = strtr($str, $smileys);
return $parsed_string;
}
When you're inserting your content into database, do not convert it into tags. Instead, when you display it, use the function ParseSmiley()
$parsed_string = mysqli_real_escape_string($con,$_POST['str']);
mysqli_query($con,"INSERT INTO tbl (comment) VALUES ($parsed_string)");
Then when you want to display the content, let's say the string is in $content, display it like this :
echo ParseSmiley($content);
I have a database set up to store user input and it then displays what they put on the page.
$input = mysql_real_escape_string(stripslashes(addslashes($_POST["input"])));
//Later on
echo '<div>'.$input.'</div>';
I went to the textarea and typed in some basic php code "<?php echo 'blahblah'; ?>," and it submitted to the database normally, but the homepage doesn't display any of it. No 'blahblah,' no tags. I want it to display the entire "<?php echo 'blahblah'; ?>" so people can post whatever they want.
Escaping needs to be appropriate for its context.
When inserting into the database, use mysql_real_escape_string (or migrate to the newer mysqli_real_escape_string, or to PDO) or read up on parameterized queries (AKA prepared statements).
When displaying in HTML, use htmlspecialchars or htmlentities.
Never use both in one go, because you will get in a mess, and never use stripslashes(addslashes(...)), because that makes no sense.
You should try the following:
echo '<div>'.htmlentities($input).'</div>';
It converts special characters like < and > to html entities so they are displayed correctly in the browser.
So I was just testing out the mysql_real_escape(); function and what that does is puts a \ before the ". The when the content is echoed back out onto the page I just get content with \'s before any ". So let's say I posted """""""""""""""""""""""""""" all I get is \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" echoed back.
Is there some code to remove the \ when it's echoed back onto the page?
By adding those slashes, mysql_real_escape_string just converts the string into the input format for the database. When the data comes out of the database, it should come out without any of the slashes. You shouldn't need to remove them yourself.
Using stripslashes like others are suggesting would do the opposite of mysql_real_escape_string in most cases, but not all of them, and you shouldn't rely on it for that purpose. Mind you, if you find yourself needing to use it for this, you've already done something else wrong.
stripslashes()
http://php.net/manual/en/function.stripslashes.php
You don't need to unescape, ie. remove the slashes - they don't get inserted into the DB. They are only for passing data to MySQL, they are not written to the db. When you SELECT the data, you won't see the slashes.
Do you know how mysql_real_escape() works. Hint: It allows to encode string for SQL usage. For example mysql_query('SELECT * FROM users WHERE name="'.mysql_real_escape_string($name).'"');. It can be used to insert string which won't escape the quotes for example like " or 1=1 -- " making SELECT * FROM users WHERE name="" or 1=1. You have to activate it just before inserting it database.
When you will read this data, slashes won't exist in any way.
Actually, looking at what is below, I will make this answer, not comment...
I need to generate a link with a Javascript confirmation dialog using Symfony's link_to() method. The confirmation dialog text gets some of it's content from a database entry:
<?php echo link_to( "click here", 'category/delete?id='.$id, array( 'confirm' => 'Are you sure you want to delete the category: '.$category->getName().'?' ) ) ?>
But if the database entry has a single quote in it, the confirm dialog doesn't work because the generated JS is surrounded with single quotes. So if I have a category called "John's Articles", the generated JS starts like this:
<a onclick="if (confirm('Are you sure you want to delete the category: John's Articles?')) { var f = document.createElement('form'); f.styl.... etc... "
So, the single quote in there screws up the confirmation, etc...
Anyways I thought I would simply run $category->getName() through addslashes() but it didn't add any slashes... I also tried saving out the category name as a separate variable ahead of time and adding slashes to that. But it didn't add any. Then I started looking at Symfony's escaping methods and found methods like esc_entities() but they resulted in the text looking like John's Articles.
What do I do? All I want to do is add in a single slash before single quotes in that string. I never tried str_replace("'","\'",$category->getName()) but THAT didn't even do anything. I can create my own basic string in my template like Alex's Test and addslashes() to it just fine. It's just this value from the database that I can't add any slashes to.
When I look at the value in the database, it looks just like John's Articles. There are no special characters or encoded characters.
What am I missing here?
UPDATE
I've tried the following code with the following results:
echo $category->getName()."<br/>";
echo addslashes($category->getName())."<br/>";
$tmp = $category->getName();
echo addslashes($tmp)."<br/>";
$tmp = addslashes($category->getName());
echo $tmp."<br/>";
$tmp = "Testing's the Testing";
echo addslashes($tmp)."<br/>";
$tmp = str_replace("'","\\'",$category->getName());
echo $tmp;
Results:
John's Articles
John's Articles
John's Articles
John's Articles
Testing\'s the Testing
John's Articles
The values from the database simply will not get slashes added to them...
Seems like you just use
addslashes($category->getName())
But you need assign returned value to other variable, ex.
$nameWithSlashes=addslashes($category->getName())
use json_encode() when inserting into Javascript. It's specifically intended to turn arbitrary data structures into syntactically valid Javascript.
<?php echo link_to( ....snip snip... category: '. json_encode($category->getName()) .'?' ) ) ?>
^^^^^^^^^^^^ ^
will take care of the problem, without any "risky" regexes/string replacements.