Abtool Kabash
Abtool Kabash

Reputation: 93

How to properly use htmlentities() and deal with XSS while still allowing quotes

Ok I have a form to create a new record. The form takes in several text fields. Prior to putting them into the database I run the fields through htmlentities($field, ENT_QUOTES). That's great. There's no way I'm vulnerable to XSS as no one can have a hope of breaking out of my fields.

For example:

Assume the user entered 'Lol <script></script>'

<div>
  <div>Description</div>
  <div>Lol &lt;script&gt;&lt;/script%gt</div>
</div>

That's well and good. The text display's nicely for the user. The following issue arrises

Assume the user entered "John O'Conner"

<div>
  <div>Name</div>
  <div><input name="name" value="John O&#u0039;Conner"</div>
</div>

That's not well and good because the field litteraly displays as "John O&#u0039;Conner". If I allow quotes then people can break out of my input fields and inject XSS.

I don't really want to just whitelist certain things if I can avoid it.

Just like on SO. When I edit a post, the quotes and any random text is still in the box, but SO is immune to XSS.

The fields are filled by an AJAX request that returns JSON data for all fields.

EDIT:

BOSS, You missed the point. I want the input fields. I just want the VALUES to display properly.

<input id="name" name="name" value="" />
.
.
.
<script>
    //AJAX request to fill fields here
</script>

If the user enters "cat" the input field becomes:

  <input id="name" name="name" value="cat" />

and the word "cat" is displayed in the box.

If the user enters John O'Conner the input field becomes:

  <input id="name" name="name" value="John O&#u0039;Conner" />

and the word "John O'Conner" is displayed in the box (not good).

If I were to allow the quotes the user could put in 'John" onmouseover="alert(3);" data-dummy="Conner' and the input field will become:

  <input id="name" name="name" value="John" onmouseover="alert(3);" data-dummy="Conner" />

EDIT: I ended up doing:

                      var dummy = $("<div></div>");
          //Itterate through the JSON object 
          $.each(returned_data, function(key,val) {
              dummy.html(val)
              $("#"+key).val(dummy.html());
          });

Upvotes: 0

Views: 728

Answers (1)

Sunil Kumar
Sunil Kumar

Reputation: 1381

Use this function to sanitize your data before inserting into database

function sanitize($data){
    $data= htmlentities(strip_tags(trim($data)));
    return $data;
} 

strip_tags() - removes tags

PHP Doc

html_entity_decode() is the opposite of htmlentities() in that it converts all HTML entities in the string to their applicable characters.

Update:

Use these best for you:

<?php    
$str = '<input value="John O" onmouseover="alert(3);" data-dummy="Conner" /> say me';
    $search = array('@<script[^>]*?>.*?</script>@si',  // Strip out javascript
                   '@<[\/\!]*?[^<>]*?>@si',            // Strip out HTML tags
                   '@<style[^>]*?>.*?</style>@siU',    // Strip style tags properly
                   '@<![\s\S]*?--[ \t\n\r]*>@'         // Strip multi-line comments including CDATA
    ); 
    $str = preg_replace($search, '', $str); 
    echo htmlentities(strip_tags($str));
?>

Output:

say me

I am taking this part from my other answer read this question Secure way

$name = "Mom's";
$db = new PDO('mysql:host=localhost;dbname=databasename', $user, $pass); 
//establish new connection

$statement = $database->prepare("UPDATE TABLE xyz SET name=?");
$statement->execute(array($name));

This will more secure itself. You don't need do manual escapes.

Or use

$msg =  mysql_real_escape_string($string);

before inserting data

Upvotes: 1

Related Questions