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.
Related
So I did an experiment with the php function htmlspecialchars() with an input from the browser. It works and the value echoed from the database does not run the script. However if I do input the script directly into the database meaning in phpMyAdmin, the codes:
<?php echo htmlspecialchars($row['fname'], ENT_QUOTES | ENT_HTML5, 'UTF-8');?>
And
<?php echo htmlspecialchars($row['lname']);?>
Still runs the javascript I put directly into the database on the browser. Does it have to do with the database collation type or something else?
JavaScript (from PHP/MySQL perspective) is just a string like any other string.
You need to know when/what/how to filter, and when/what/how to escape.
Filter: Is filtering out malicious strings before inserting it into database. Like the function strip_tags()
Escape: Is escaping characters (like ", ', <, >, etc) before printing out result that may give you undesired output. Like the function htmlspecialchars()
Warning
Storing JavaScript in DB then outputting it into browser is easy, but also dangerous! Make sure only admin users are allowed to do that.
I want to make sure my sanitize doesnt have any leaks in it.
And also, im only outputting user-data within hardcoded p tags and h1 tags
eg : <p><?php echo htmlspecialchars($user_data); ?></p>
So is this a safe way to protect me against XSS-injects.
First, im using this function to sanetize the data before it gets inserted into my DB, and while in my DB im using bind_param
function sanitize($str) {
return strtolower(strip_tags(trim(($str))));
}
sanitize($user_data); - > then gets inserted into db
Then when I grap the data from the DB I am using this to show it.
<p> <?php echo htmlspecialchars($user_data); ?> </p>
So, is this a safe way to block any XSS?
Thanks!
From a security standpoint, there is no need to use your sanitize function as long as you escape / process your data correctly for the medium you are outputting to:
Using htmlspecialchars() is all that is needed for output to html;
Use json_encode if you need to output to javascript;
Use prepared statements with bound variables for your database;
etc.
I've recently thrown together a basic PHP webpage that lists information pulled from an MySQL table and displays it in various sorts. I'm wanting to allow the user to add a new item to the table, edit an item in the list and delete an item in the list without refreshing the page (Ajax).
This currently goes;
To add/edit an article you click on a link which prompts the popover ajax form, and fills it's contents (if editing) by performing the function setEdit(comment) as below;
<a class="popup-button" title="<?php echo $row['comment']; ?>" onclick="setEdit('<?php if($row['comment']){ echo $row['comment']; } else { echo "Enter comment here..."; } ?>');"><?php echo $row['listitem']; ?></a>
The setEdit() comment is as follows;
function setEdit(editcomment)
{
if(editcomment){ document.getElementById('help-us-comment').value=editcomment; }
}
Which is then, after submitting the ajax form, handled by the following php code;
if(isset($_POST['comment_text']))
$comment=$_POST['comment_text'];
$sql = "INSERT INTO table SET
comment='$comment'";
Problem: I'm having constant issues trying to get the database contents through 1, 2, 3 without falling over at a new line, single or double quote. I've tried endless combinations of replacing tags, htmlspecialchars and nl2br with no half successes - where it's got to the point that it's so convoluted and encoded/decoded now that I'm assuming that there is a far simpler and obvious way that I'm missing.
The main problem happens when trying to load the data into the form, typically having either the form fall over and refuse to populate at all (typically by the a link becoming broken by the data extracted i.e. single quote or new line) or the form being populated with special characters instead of plain text to edit.
I've tried to go into as much detail as possible, but if any more is needed I'm happy to provide. Also apologies if this is an obvious fix/mistake, and I'm being an idiot.
You have two problems here: storing and displaying.
To display you should look in to htmlentities that makes it safe HTML (it does all the quotes replacing, html encoding, etc. for you) so that your string to be safe to be displayed as plain text, or as inputs' values.
To store the data, you should sanitize your queries. You could use mysqli and bind parameters, or use mysql_real_escape_string to escape your input manually.
Otherwise, say hi to Bobby Tables ;)
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.
I am beginner in web development, I am developing a site that allows user to post various discussions and others comment and reply on it. The problem I am facing is, the user can post almost anything, including code snippets and any other thing which might possible include single quotes, double quotes and even some html content.
When such posts are being posted, it is intervening with the MySQL insert query as the quotes are ending the string and as a result the query is failing. And even when I display the string using php, the string is being interpreted as html by the browser, where as I want it to be interpreted as text. Do I have to parse the input string manually and escape all the special characters? or is there another way?
You need to read up on a few things
SQL Injection - What is SQL Injection and how to prevent it
PHP PDO - Using PHP PDO reduces the risk of injections
htmlentities
The basic premise is this, sanitize all input that is coming in and encode everything that is going out. Don't trust any user input.
If possible, whitelist instead of blacklisting.
EDIT :
I you want to display HTML or other code content in there, users need to mark those areas with the <pre> tag. Or you could use something like a markdown variation for formatting.
Use PDO, prepared statements and bound parameters to insert / update data, eg
$db = new PDO('mysql:host=hostname;dbname=dbname', 'user', 'pass');
$stmt = $db->prepare('INSERT INTO table (col1, col2) VALUES (?, ?)');
$stmt->execute(array('val1', 'val2'));
Edit: Please note, this is a very simplified example
When displaying data, filter it through htmlspecialchars(), eg
<?php echo htmlspecialchars($row['something'], ENT_COMPAT, 'UTF-8') ?>
Update
As noted on your comment to another answer, if you want to maintain indentation and white-space when displaying information in HTML, wrap the content in <pre> tags, eg
<pre><?php echo htmlspecialchars($data, ENT_COMPAT, 'UTF-8') ?></pre>
Look at mysql_real_escape_string and htmlentities functions in PHP manual.
You can also read the Security chapter in PHP manual.
To avoid the breaking of queries in database (which means you're not escaping them, leaving big holes for sql injection) you use mysql_real_escape_string($string) on the value before passing it to the query string, enclosing it in quotes also.
Ex. $value = mysql_real_escape_string($value); // be sure to have an open connection before using this function.
$query = "select * from `table` where value = '".$value."'";
As for displaying in html, you should at least echo htmlentities($string) before outputting it to the browser.
Like echo htmlentities($mystring, ENT_QUOTES)`;
Edit:
To preserve withe spaces, you can use nl2br function (which converts linebrakes to the html equivalen <br />) or go for a little deeper $string = nl2br(str_replace(" ", " ", $string));, but html code would look a bit ugly, at least for me
Reference: htmlentities and mysql_real_escape_string. nl2br
use mysql_real_escape_string. It is a good practice to use this on all user inputs to prevent SQL Injection attacks.