0

I want to protect my website from XSS attacks. For that I am using htmlentites. When I am trying to insert my variable into MySQL I am getting an error?

$var = htmlentities("<script>alert('hello')</script>");
$conn = mysqli_connect("localhost","root","","xss");
//mysqli_query($conn,"INSERT INTO entities (ent) VALUES('$var')");
if (!mysqli_query($conn,"INSERT INTO entities (ent) VALUES('$var')"))
{
    echo("Error description: " . mysqli_error($conn));
}
echo $var; 
Dharman
  • 30,962
  • 25
  • 85
  • 135
  • Possible duplicate of [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) – Gabor Lengyel Nov 09 '19 at 21:25

2 Answers2

1

The correct answer is you you are not supposed to do this. Don't store the result of htmlentities() in the database. This function is meant to be used only when you output in HTML context! You can't know for sure if the data stored in the database will always be used in HTML context.
XSS-prevention is very context-dependent. What if you would like to output to JavaScript or CSV or simply search the values in the database? You can't do it if they are encoded for HTML output.

To answer your more pressing issue I need to mention that your code is vulnerable to SQL injection. Use prepared statements with parameter binding.

The correct mysqli example of INSERT query would be as follows:

<?php

$var = "<script>alert('hello')</script>";

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli("localhost", "root", "", "xss");
$conn->set_charset('utf8mb4');

$stmt = $conn->prepare('INSERT INTO entities (ent) VALUES(?)');
$stmt->bind_param('s', $var);
$stmt->execute();

// use htmlentities when in HTML context
echo '<div>'.htmlentities($var).'</div>';
Dharman
  • 30,962
  • 25
  • 85
  • 135
-2

You can use the mysqli_real_escape_string() function to sanitize the data before inserting into the database

$var = htmlentities("<script>alert('hello')</script>");
 $conn = mysqli_connect("localhost","root","","xss");
// add this line to sanitize the string before inserting into the database
$var = mysqli_real_escape_string($conn, $var);
if (!mysqli_query($conn,"INSERT INTO entities (ent) VALUES('$var')"))
 {
    echo("Error description: " . mysqli_error($conn));
 }
 echo $var; 

Hope this help

  • mysqli_real_escape_string() does not "sanitize the data". Prepared statement does – Your Common Sense Nov 11 '19 at 19:27
  • @YourCommonSense To be correct, prepared statement doesn't sanitize the data either. Sanitizing would involve removing unwanted values. That word is too ambiguous. – Dharman Nov 11 '19 at 21:34