简体   繁体   English

我可以正确使用htmlspecialchars吗?

[英]Do i use the htmlspecialchars correctly?

I am trying to filter the user's input from malicious code to prevent XSS attack. 我正在尝试从恶意代码中过滤用户的输入,以防止XSS攻击。 When the user submits the input, the input goes trough the following checks... The input is contained in the $post variable. 当用户提交输入时,输入将通过以下检查...输入包含在$ post变量中。

$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? 但是我看不到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? htmlspecialchars命令仅用于输出吗?

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. htmlspecialchars是删除所有HTML特殊字符,并用“与”代码替换它们,该字符将显示该字符但不会被解释为HTML。 This is highly effective against XSS Attacks (but not SQL Injection). 这对XSS攻击非常有效(但对SQL注入无效)。

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. 这意味着,如果通过htmlspecialchars放置字符串<script>malicousCode</script>并将其回显到页面中,则用户将看到实际的字符串。 If you do not put it through htmlspecialchars the browser would think that it's a <script> tag and execute malicousCode. 如果不通过htmlspecialchars放置它,浏览器将认为它是<script>标记并执行malicousCode。

This in itself does not prevent SQL Injection! 这本身并不能防止SQL注入! 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) 为了防止SQL注入使用预处理语句(我不鼓励您使用其他形式的转义,例如mysqli_real_escape_string因为使用预处理语句使其完全不可能)

Yes, this is a correct usage of htmlspecialchars 是的,这是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): 上面代码的HTML输出为(查看源代码):

<!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. htmlspecialchars()函数将一些预定义的字符转换为HTML实体。

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; htmlspecialchars编码html字符,例如<tag>将替换为&lt;tag&gt; . When you load that string back from database and display it, the browser will still display &lt;tag&gt; 当您从数据库加载该字符串并显示它时,浏览器仍会显示&lt;tag&gt; as <tag> , but it won't be treated as html instruction by the browser. <tag> ,但浏览器不会将其视为html指令。 So in the page source, you will still see the encoded &lt;tag&gt; 因此,在页面源中,您仍然会看到编码后的&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. 如果要使用页面上的字符串,以便将其解释为普通的html命令,则在从数据库中加载内容后,必须使用htmlspecialchars_decode (Docs)将其转换回。

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. 如果出于安全考虑要转义输入以保护您免受sql注入,则可以改用mysqli_real_escape_string

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: 因此,使用mysqli预处理语句的示例将是:

$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. 请注意,我没有任何错误处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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