简体   繁体   中英

Do i use the htmlspecialchars correctly?

I am trying to filter the user's input from malicious code to prevent XSS attack. When the user submits the input, the input goes trough the following checks... The input is contained in the $post variable.

$post = htmlspecialchars($post);
    $id = $_SESSION['loggedIn'];
    $sql = "UPDATE playerstats SET message='$post' WHERE id = $id";
    $db->query($sql);
    header("location: ?page=message");

Yeah i know i am not using prepared statements, but i made that code just for testing purposes. Okay, it works. In the database i see

<script>top.location.href = "?page=message";</script>

So in that message page i see the post that was just inserted. But i don't see the effect of htmlspecialchars? It affected the post when it got submitted to the database, but when i display it in the message page.. i see again

<script>top.location.href = "?page=message";</script>

Any idea why this is happening? Is the htmlspecialchars command only meant to be for output?

The point of htmlspecialchars is to remove any HTML special characters and replace them with Ampersand-Codes which will show the character but not get interpreted as HTML. This is highly effective against XSS Attacks (but not SQL Injection).

That means if you put the string <script>malicousCode</script> through htmlspecialchars and echo it into the page, the user will see the actual string. If you do not put it through htmlspecialchars the browser would think that it's a <script> tag and execute malicousCode.

This in itself does not prevent SQL Injection! It is only used to sanitize strings which you want to show to the user.

To prevent SQL Injection use prepared statements (I discourage you from using any other forms of escaping like mysqli_real_escape_string because using prepared statements makes it completely impossible)

Yes, this is a correct usage of htmlspecialchars

$post = htmlspecialchars($post);

and here are another example:

<?php
$str = "This is some <b>bold</b> text.";
echo htmlspecialchars($str);
?>

The HTML output of the code above will be (View Source):

<!DOCTYPE html>
<html>
<body>
This is some &lt;b&gt;bold&lt;/b&gt; text.
</body>
</html> 

The browser output of the code above will be:

This is some <b>bold</b> text.

summary:

The htmlspecialchars() function converts some predefined characters to HTML entities.

The predefined characters are:

& (ampersand) becomes &amp;
" (double quote) becomes &quot;
' (single quote) becomes &#039;
< (less than) becomes &lt;
> (greater than) becomes &gt;

htmlspecialchars encodes html characters, for example <tag> will be replaced with &lt;tag&gt; . When you load that string back from database and display it, the browser will still display &lt;tag&gt; as <tag> , but it won't be treated as html instruction by the browser. So in the page source, you will still see the encoded &lt;tag&gt; .

If you want to use the string on the page so it gets interpreted as normal html command, you have to use htmlspecialchars_decode (Docs) to convert it back after you loaded the content back from the database.

loaded_from_db = htmlspecialchars_decode(value);

If you want to escape your input because of security considerations to protect you from sql injections, you could use mysqli_real_escape_string instead.

But using prepared statements would be the best choice, because you define exactly what you expect as parameters for your statements and the values provided cannot mess it up. It's also the recommended approach even if it's just for testing purpose and it's not that hard to implement.

so your example with mysqli and prepared statements would be:

$stmt = $mysqli->prepare("UPDATE playerstats SET message=? WHERE id = ?");    
$stmt->bind_param("si", $post, $id)
$stmt->execute()

note that I didn't include any error handling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM