Best practice for PHP output - php

I was wondering, whats the best practice on the example below.
<?php
if(isset($_POST['query'])){
$out = $_POST['query'];
}
?>
<div><?php echo $out; ?></div>
<input type="text" value="<?php echo $out; ?>" />
Using the above code would this pose a threat to website. Or would I need to prepare the output before using it as above. By prepare I mean encode it or escape special characters.
I am aware you need to escape it and validate inputs for db use, how about for outputting it?

Yes, since you’re putting it out into HTML you should use encode HTML’s special characters appropriately with htmlspecialchars:
if (isset($_POST['query'])) {
$out = htmlspecialchars($_POST['query']);
}
Besides that, $out is only defined when $_POST['query'] exists; you should think about having a default value if $_POST['query'] does not exist. Because otherwise, when register globals are enabled (that alone is a bad idea) you could set that variable via the URL query string with ?out=….

Yes, you should be using the php function htmlspecialchars
http://php.net/manual/en/function.htmlspecialchars.php
also, see this (accepted answer)
Do htmlspecialchars and mysql_real_escape_string keep my PHP code safe from injection?

dont know about best practise and that depend on the coder i like turnary
echo (isset($_POST['query']))? htmlspecialchars($_POST['query']):"";

Related

The secure way to use GET parameter in the DOM?

Here is a simplified of my code:
$html = "<a class='myclass' href='/path?arg='" . $_GET['param']. "'>mylink</a>";
Today I was reading about XSS attack and I think my code is under XSS attack. Howver I'm not sure, but it smells that.
Anyway, if my thought is right, how can I avoid that? Based on some researches, one way is using strip_tags(). Now I want to know, can I rely on it? And is that fine enough?
This is about encode something with the correct function.
Always look what you want to product, then choose the encoder!
Samples:
When you are building HTML its good to use htmlspecialchars and/or htmlentities.
When you are build SQL its good to use for mysql PDO::quote or mysqli_real_escape_string.
Answer:
In your case, you are building an URL. For this you need to use urlencode.
In addition you also need to escape it to correct HTML with htmlentities, because you are building HTML in the next step.
See the sample in PHP manual -> urlencode link (Example #2).
You should use htmlspecialchars() whenever you want to output a parameter that came from user.
$variable = htmlspecialchars($_GET['param'], ENT_QUOTES, 'UTF-8');

PHP: Scripting (XSS_in_URI.script)

When I check my script with Acunetix vuln scanner i see this XSS error :
This vulnerability affects /cms/search.php.
Discovered by: Scripting (XSS_in_URI.script).
Attack details
URI was set to "onmouseover='prompt(961413)'bad=">
The input is reflected inside a tag parameter between double quotes.
in search.php page i safe all user input with this:(safeXSS name of anti XSS function)
if (isset($_POST['search'])) {
$search = array_map ('safeXSS', $_POST);
}
else
{
$search = array_map ('rawurldecode', $_GET);
$search = array_map ('safeXSS', $search);
}
search form input:
<input type="submit" name="search" class="submit" value="search" />
I do not understand what's my problem?! how do i can fix this?
In your PHP template somewhere you will have code like:
<a href="<?php echo $uri ?>">
or:
echo "<a href=\"$uri\">";
HTML-escaping is missing here, so if a quote character is included in the value in $uri then that URI content escapes the attribute value it is supposed to be contained in, and you get dangerous output:
<a href=""onmouseover='prompt(961413)'bad=">">
You should fix this by calling htmlspecalchars() each and every time you output a plain text string into HTML text content or attribute values:
<a href="<?php echo htmlspecialchars($uri, ENT_QUOTES 'utf-8') ?>">
(You can make this less obtrusive by defining a short-named function like h() that calls echo htmlspecialchars for you. Or, in the longer term, prefer to use a template language that does this automatically for you.)
The filtering you've got on $_POST/$_GET is not at all effective. It is unclear what safeXSS is doing exactly, and I have absolutely no idea what rawurldecode is there for, but in general it is not possible to implement correct handling of string escaping at the input stage.
Using input ‘sanitisation’ to attempt to combat XSS is a common antipattern that should be avoided. (You may want to do custom input filtering for other reasons, but it's the wrong way to handle injection/escaping problems.) HTML-injection, JavaScript-injection, XML-injection and so on are output-stage concerns; the input stage doesn't know what contexts input is going to be used in yet, so can't treat the input in the correct way for that output context.

nl2br() won't output line breaks, just 'n'

It's pretty simple, I have a text area post on my website, and if I input:
line 1
line 2
line 3
into it, it outputs:
line 1nline 2nline 3
My insert code is:
$status = strip_tags(stripslashes(htmlentities(mysql_real_escape_string($_POST['status']))));
$uid = strip_tags(stripslashes(htmlentities(mysql_real_escape_string($_POST['uid']))));
//more stuff
$sid = rndTxt(16);
$status = nl2br($status);
if (!get_magic_quotes_gpc()) {
$status = addslashes($status);
}
$insert = mysql_query("INSERT INTO mingle_status (uid,sid,status,`timestamp`) VALUES ('$uid','$sid','$status',now())") or
print mysql_error();
and my output code:
while($st = mysql_fetch_assoc($statussql)) {
$status = stripslashes($st['status']);
$sid = $st['sid'];
$td = $st['timestamp'];
?>
<div id="n">
<div id="statuses" class="<?php echo $sid; ?>">
<p><?php echo $status; ?></p>
<div id="statuscomadd" style="background:#E0E0E0;">
Like Dislike<?php echo time_since($td) . " ago"; ?>
</div>
</div>
Any help would be greatly appreciated!:)
you dont need to use nl2br() on insert, you will have to use it while displaying in html
and will have to remove stripslashes before insert
When inserting just do a mysql_real_escape_string() over the values. You only want to change the data (e.g. by using htmlentities() when you are going to display it).
Please also consider to stop using mysql_* functions for new code. They are no longer maintained and the community has begun the deprecation process. See the red box? Instead you should learn about prepared statements and use either PDO or MySQLi. If you can't decide, this article will help to choose. If you care to learn, here is a good PDO tutorial.
Another thing: do you realy need htmlentities()? Because imo a better solution is to use htmlspecialchars(). Otherwise all html entities will be replaced.
Also I don't think you need to use strip_tags(), because you are already doing htmlspecialchars() to protect you against XSS.
Now for you problem is it because you are using stripslashes() which breaks the \n linebreaks. I think you can just drop those add/stripslashes.
You use strip_tags(stripslashes(htmlentities(mysql_real_escape_string()))); which strips the slashes from \n.
Just use mysql_real_escape_string(), or htmlentities( ,ENT_QUOTES) for HTML.
Also, if it's possible use an UTF-8 encoding and htmlspecialchars() instead of htmlentities(). htmlentities() converts every character which has an HTML-representation, while htmlspecialchars() converts only the necessary characters. There's no need to convert everything. See: htmlentities vs htmlspecialchars

Prevent XSS attacks

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);

extra /// when pulling info from database

i am using a funstion to insert data into the database
so here is where it inserts
i am inserting this
<div class="widget" id="recentcomments"><h2>Blog</h2></div>
update_option("head-text", mysql_real_escape_string($head_text));
so it inserts into the database and when i save and pull it back out like below.
<input type="text" name="head-text" id="head-text" class="regular-text" value="<?php echo htmlentities($head_text, ENT_QUOTES); ?>"/>
i get the following.
<div class=\\\"widget\\\" id=\\\"recentcomments\\\"><h2>Blog</h2></div>
loads off \\\\
sorry for the vag question before.
According to the manual mysql_real_escape_string
If magic_quotes_gpc is enabled, first
apply stripslashes() to the data.
Using this function on data which has
already been escaped will escape the
data twice.
You can go for a function like this (in case you don't want to use prepared statements)
function safe($input)
{
if (get_magic_quotes_gpc())
{
$input = stripslashes($input);
$escaped = mysql_real_escape_string($input);
}
else
{
$escaped = mysql_real_escape_string($input);
}
return $escaped;
}
There's no need to call stripslashes() on output if SQL escaping is done properly
You have your data escaped twice before it gets inserted into database.
You have to find what causing this, and turn off excessive escaping.
It could be magic_quotes_gpc setting.
In this case you have to turn off this setting in the PHP configuration.
And add a code that checks get_magic_quotes_gpc() result and strips slashes from all superglobal arrays.
if magic quote are certainly turned on,
It could be also just mysql_real_escape_string/addslashes being called twice in your code. You have to search your code for this and get rid of one which is called earlier than anaother
Thanks for the replies got it working with the following.
<?php echo htmlentities(stripslashes($head_text)); ?>
needed them both

Categories