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.
Related
Is this code secure to prevent XSS attacks ??
<?php
$string = "<b>hello world!</b>";
echo "without filtering:".$string;
echo "<br>";
$filtered = htmlspecialchars($string); // insert into database filtered
echo "After filtering:".$filtered;
echo "<br>";
$de_filtering = htmlspecialchars_decode($filtered); //retrieve from database and display
echo "After de-filtering:".$de_filtering;
?>
You should not encode HTML-Specialchars when inserting into database, that way data is manipulated (and maybe different when editing the dataset). You should rather encode them when displaying it.
But yes, htmlspecialchars() is enough to prevent XSS as long as you don't forget to use it. The way YOU use it however is as secure as before. XSS is prevented through the encoded version, the database does not care about it.
No, XSS is independent of the database. To avoid SQL-injection, you want to escape using something like mysql_real_escape_string or use prepared statements, but to avoid XSS you need to escape when outputting to HTML.
And there are a couple of gotchas there as well. Take a look at the OWASP XSS prevention cheat sheet. It explains how to escape for different context.
htmlspecialchars/htmlentities will protect you if you are outputting untrusted data between tags, but will not protect you if you are outputting it in say a javascript event handler like this:
<button onclick="confirm('do you want to delete <?php echo htmlspecialhars($untrusted_data) ?>')">
This is because you are escaping for HTML and not javascript.
Nope - you're filtering the data before putting it into the database (which is unnecessary), but cancelling out the filter when outputting the data.
Store the data in the database unfiltered, and escape it when outputting:
echo htmlspecialchars($unfiltered_data_from_database);
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.
Is this code secure to prevent XSS attacks ??
<?php
$string = "<b>hello world!</b>";
echo "without filtering:".$string;
echo "<br>";
$filtered = htmlspecialchars($string); // insert into database filtered
echo "After filtering:".$filtered;
echo "<br>";
$de_filtering = htmlspecialchars_decode($filtered); //retrieve from database and display
echo "After de-filtering:".$de_filtering;
?>
You should not encode HTML-Specialchars when inserting into database, that way data is manipulated (and maybe different when editing the dataset). You should rather encode them when displaying it.
But yes, htmlspecialchars() is enough to prevent XSS as long as you don't forget to use it. The way YOU use it however is as secure as before. XSS is prevented through the encoded version, the database does not care about it.
No, XSS is independent of the database. To avoid SQL-injection, you want to escape using something like mysql_real_escape_string or use prepared statements, but to avoid XSS you need to escape when outputting to HTML.
And there are a couple of gotchas there as well. Take a look at the OWASP XSS prevention cheat sheet. It explains how to escape for different context.
htmlspecialchars/htmlentities will protect you if you are outputting untrusted data between tags, but will not protect you if you are outputting it in say a javascript event handler like this:
<button onclick="confirm('do you want to delete <?php echo htmlspecialhars($untrusted_data) ?>')">
This is because you are escaping for HTML and not javascript.
Nope - you're filtering the data before putting it into the database (which is unnecessary), but cancelling out the filter when outputting the data.
Store the data in the database unfiltered, and escape it when outputting:
echo htmlspecialchars($unfiltered_data_from_database);
I have a text box on my site that allows the use of html formatting to allow the users to make the text more presentable.
I use this code to protect most inputs to my db.
function clean($str) {
$str = #trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
What i don't want it to do is remove html elements like <p> and <strong>
is there a better way to protect the inputs in text areas?
I only use mysql_real_escape_string() when inserting data to my DB and remove Tags like <script> (and some others) after pulling it from the DB. I think there are a few regexes out there.
The first line of defense against injections is using prepared statements. If you use prepared statements for your queries then it really doesn't matter what the user puts into your form because you have already separated code from data. The database will see any code that a user injects as just data rather than code. So not only do you get the benefit of protecting yourself from injection, but your code is actually cleaner and more thought out as well.
I want to display on screen data send by the user,
remembering it can contain dangerous code, it is the best to clean this data with html entities.
Is there a better way to do html entities, besides this:
$name = clean($name, 40);
$email = clean($email, 40);
$comment = clean($comment, 40);
and this:
$data = array("name", "email," "comment")
function confHtmlEnt($data)
{
return htmlentities($data, ENT_QUOTES, 'UTF-8');
}
$cleanPost = array_map('confHtmlEnt', $_POST);
if so, how, and how does my wannabe structure
for html entities look?
Thank you for not flaming the newb :-).
"Clean POST", the only problem is you might not know in what context will your data appear. I have a Chat server now that works via browser client and a desktop client and both need data in a different way. So make sure you save the data as "raw" as possible into the DB and then worry about filtering it on output.
Do not encode everything in $_POST/$_GET. HTML-escaping is an output-encoding issue, not an input-checking one.
Call htmlentities (or, usually better, htmlspecialchars) only at the point where you're taking some plain text and concatenating or echoing it into an HTML page. That applies whether the text you are using comes from a submitted parameter, or from the database, or somewhere else completely. Call mysql_real_escape_string only at the point you insert plain text into an SQL string literal.
It's tempting to shove all that escaping stuff in its own box at the top of the script and then forget about it. But text preparation really doesn't work like that, and if you pretend it does you'll find your database irreparably full of double-encoded crud, backslashes on your HTML page and security holes you didn't spot because you were taking data from a source other than the (encoded) parameters.
You can make the burden of remembering to mysql_real_escape_string go away by using mysqli's parameterised queries or another higher-level data access layer. You can make the burden of typing htmlspecialchars every time less bothersome by defining a shorter-named function for it, eg.:
<?php
function h($s) {
echo(htmlspecialchars($s, ENT_QUOTES));
}
?>
<h1> Blah blah </h1>
<p>
Blah blah <?php h($title); ?> blah.
</p>
or using a different templating engine that encodes HTML by default.
If you wish to convert the five special HTML characters to their equivalent entities, use the following method:
function filter_HTML($mixed)
{
return is_array($mixed)
? array_map('filter_HTML',$mixed)
: htmlspecialchars($mixed,ENT_QUOTES);
}
That would work for both UTF-8 or single-byte encoded string.
But if the string is UTF-8 encoded, make sure to filter out any invalid characters sequence, prior to using the filter_HTML() function:
function make_valid_UTF8($str)
{
return iconv('UTF-8','UTF-8//IGNORE',$str)
}
Also see: http://www.phpwact.org/php/i18n/charsets#character_sets_character_encoding_issues
You need to clean every element bevor displaying it. I do it usually with a function and an array like your secound example.
If you use a framework with a template engine, there is quite likely a possibility to auto-encode strings. Apart from that, what's simpler than calling a function and getting the entity-"encoded" string back?
Check out the filter libraries in php, in particular filter_input_array.
filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);