Jump to content

Security concerns while displaying output to a browser


ajoo
Go to solution Solved by Jacques1,

Recommended Posts

Hi friends, 

 

Another security issue but this time its regarding outputting data from a DB to a browser. Please have a look at the code below which displays some output fetched from a DB and sends it to a browser. 

 

1. If I just wish to display this output on a screen and not provide the user with any buttons or hyperlinks to interact with the information, would I still need to sanitize the output before echoing it to the screen ? 

 

2. If I was to make at least one of the fields a hyperlink, so that I could then display some related information on another webpage, what security concerns would I need to address in my code?

 

3. If I was to add a button against each of these records, on each row, and then select some related  information on another webpage after processing the button handler, what would be the security concerns that I should address for the code below. 

 

Thanks very much.

<table>

<tr>
<th> S.No. </th>
<th> Name </th>
<th> Age </th>
<th> City </th>
<th> Cell </th>
<th> Email</th>
</tr>

<?php 
$cnt = 1;
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC))
{
echo "<tr>";
echo "<td>".$cnt++."</td>";
echo "<td>".$row['Name']. "</td>";
echo "<td>".$row['Age']. "</td>";
echo "<td>".$row['City']. "</td>";
echo "<td>".$row['Cell']. "</td>";
echo "<td>".$row['Email']. "</td>";
echo "</tr>";
}
?>
</table>
Link to comment
Share on other sites

#1: Since I have no clue what the source of this information is, the answer would be Yes. Always assume data could be malicious and take appropriate precautions. So, for this you can just use htmlentities() or htmlspecialchars() when outputting those field values. I prefer to 'prepare" the data before outputting - instead of doing it in-line. Plus, put your "Logic" at the top of the page (or even in a separate file)

<?php 
 
## PUT ALL THE PHP LOGIC AT THE TOP OF YOUR SCRIPT
## CREATE VARIABLES THAT ARE OUTPUT IN THE HTML OUTPUT
 
$user_list_HTML = '';
$cnt = 0;
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC))
{
    $cnt++;
    $name  = htmlspecialchars($row['Name']);
    $age   = htmlspecialchars($row['Name']);
    $city  = htmlspecialchars($row['Name']);
    $cell  = htmlspecialchars($row['Name']);
    $email = htmlspecialchars($row['Name']);
    $user_list_HTML .= "<tr>\n";
    $user_list_HTML .= "    <td>{$cnt}</td>\n";
    $user_list_HTML .= "    <td>{$name}</td>\n";
    $user_list_HTML .= "    <td>{$age}</td>\n";
    $user_list_HTML .= "    <td>{$city}</td>\n";
    $user_list_HTML .= "    <td>{$cell}</td>\n";
    $user_list_HTML .= "    <td>{$email}</td>\n";
    $user_list_HTML .= "</tr>\n";
}
?>
<html>
<head></head>
<body>
 
<table>
  <tr>
    <th> S.No. </th>
    <th> Name </th>
    <th> Age </th>
    <th> City </th>
    <th> Cell </th>
    <th> Email</th>
  </tr>
  <?php echo $user_list_HTML; ?>
</table>
 
</body>
</html>

#2: There is nothing in that code that would make sense to be a link. You would likely want to include the primary ID frm that table and use THAT in the link. Something like

echo "<td><a href='get_user_data.php?id={id}'>{$name}</a></td>\n";

And, in that case you could use intval() on the ID, but that probably isn't necessary since the ID would be database defined and would never be set by an external source. However, on the get_user_data,php page you *would* need to add validation to ensure the id passed is valid and/or escaped to prevent SQL injection

 

#3: I would assume the button would do something similar as the link and just pass the id of the record to be processed. So, the same applies. Not necessary to validate on the page that creates the button since the value is programatically created in the database (but it doesn't hurt to add some logic). but, you would definitely need to validate/sanitize on the receiving page.

Edited by Psycho
Link to comment
Share on other sites

Hi ! Thanks for the reply. 

 

#1. The source of this information would be a Mysql database. But yes I will use htmlspecialchars().

 

#2. For the second case I mentioned the hyperlink because that is passed through the URL and I thought that that maybe be a cause of a security concerns which should be addressed.

 

#3. Yes this would be just like the #2 as you have mentioned and for this I would need to validate the post data submitted.

 

If there is anything that you would like to add to the first 2 cases.

Thanks  

Link to comment
Share on other sites

#1. The source of this information would be a Mysql database. But yes I will use htmlspecialchars().

 

No, it is not. The database isn't going to magically create names, ages, etc. It does automatically create auto-increment IDs. The latter are the types of values that you don't, necessarily, need to validate because you know they will be the type that you expect. As for the names, ages, etc. The values are being entered 'somewhere', but I don't know who is entering or what logic is applied before the data is saved. Although you *could* perform validations/sanitizing before storing the data in the database, you would not want to rely upon that during the output process. Don't create a process that *assumes* something is being done by a separate process.

Link to comment
Share on other sites

  • Solution

You must specifiy the character encoding when you escape data. Without this, you're flying blind. If you're lucky, the browser will pick the same encoding which htmlspecialchars() happens to use by default, but this definitely isn't something you should rely on.

 

For example, Internet Explorer is infamous for “guessing” the encoding if there's no explicit declaration. An attacker can use this to bypass escaping entirely: They give you a string which is harmless when interpreted with your default encoding, so htmlspecialchars() takes no action. But when Internet Explorer does its guessing and chooses a different encoding, the harmless string suddenly turns into malicious HTML.

 

Try this in any version of Internet Explorer:

<?php

// Mimic the guessing behaviour of IE 7 and earlier.
header('Content-Type: text/html;charset=utf-7');

$input = "+ADw-script+AD4-alert('XSS!')+ADw-/script+AD4-";

/*
 * Since you forgot to tell htmlspecialchars() which character encoding it should use, it will
 * assume ISO 8859-1 or UTF-8 depending on the PHP version. When $input is interpreted with those
 * encodings, it's meaningless and will not be touched by htmlspecialchars(). Unfortunately, the
 * client uses UTF-7! And in that case, the input means this: <script>alert('XSS!')</script>
 */
$maybe_safe = htmlspecialchars($input);

// There's our XSS vulnerability, regardless of the fact that we've used htmlspecialchars().
echo $maybe_safe;

So escaping without an encoding declaration is futile. You first need to define the character encoding of your HTML document if you haven't done that already:

// If you're not using UTF-8, change this accordingly.
header('Content-Type: text/html;charset=utf-8');

And then you need to use this exact encoding for htmlspecialchars(). It's probably best to write a custom wrapper function:

function html_escape($input, $encoding)
{
	/*
	 * Note the flags:
	 *
	 * ENT_QUOTES tells the function to escape both single and double quotes.
	 * Otherwise, single quotes will be ignored and can be used for attacks.
	 *
	 * ENT_SUBSTITUTE tells the function to replace invalid Unicode sequences
	 * with an error symbol. Otherwise, the entire input will be replaced with
	 * an empty string, which is probably not what you want.
	 */
	return htmlspecialchars($input, $encoding, ENT_QUOTES | ENT_SUBSTITUTE);
}
Edited by Jacques1
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.