防止 XSS 攻击。

3

这段代码是否安全,可以防止XSS攻击?

<?php
   $string = "<b>hello world!</b>";
   echo "without filtering:".$string;
   echo "<br>";
   $filtered = htmlspecialchars($string); // insert into database filtered
   echo "After filtering:".$filtered;
   echo "<br>";
   $de_filtering = htmlspecialchars_decode($filtered); //retrieve from database and display
   echo "After de-filtering:".$de_filtering;        
  ?>

这是朝着正确方向迈出的一步。你需要展示更多代码,来自你的应用程序的真实世界示例。仅凭这些理论还不够。 - Paul Dessert
2
如果你要将数据存入数据库中,请不要使用htmlspecialchars,而是使用你所用数据库的转义方法(例如mysql_real_escape_string)。 - gen_Eric
2
@Rocket 更好的做法是使用PDO和预处理语句来代替手动转义数据库输入。PHP核心开发团队真的很想摆脱过时的mysql/mysqli扩展,但由于许多人坚持继续使用它们,他们无法这样做。对于每个人:请尽你的一份力量,鼓励使用预处理语句而不是手动转义。 - user895378
3个回答

8

在插入数据库时,不应该对HTML-Specialchars进行编码,这样数据会被篡改(可能与编辑数据集时不同)。相反,在显示数据时应该进行编码。

但是,只要你不忘记使用htmlspecialchars(),它就足以防止XSS攻击。然而,你使用它的方式和以前一样安全。XSS攻击是通过编码版本来预防的,数据库并不关心它。


4
你几乎说的都对,但请仔细查看原帖中的代码 - 他使用 htmlspecialchars() 的方式并不能防止跨站脚本攻击。 - Pekka
使用htmlspecialchars是否起作用取决于上下文。请参见我下面的回答。 - Erlend

5

不,XSS与数据库无关。为了避免SQL注入,您需要使用诸如mysql_real_escape_string或准备语句等方式进行转义,但为了避免XSS,您需要在输出到HTML时进行转义。

还有一些需要注意的地方。请参考OWASP XSS prevention cheat sheet。它解释了如何在不同的上下文中进行转义。

如果要在标签之间输出不受信任的数据,则htmlspecialchars/htmlentities将保护您,但如果您要在例如JavaScript事件处理程序中输出它,则不会保护您:

&lt;button onclick="confirm('do you want to delete &lt;?php echo htmlspecialhars($untrusted_data) ?&gt;')"&gt;

这是因为你正在转义 HTML 而不是 JavaScript。

1

不对 - 你在将数据放入数据库之前进行了过滤(这是不必要的),但在输出数据时取消了过滤。

将数据存储在未经过滤的数据库中,并在输出时进行转义:

 echo htmlspecialchars($unfiltered_data_from_database);

在把数据存入数据库之前一定要使用 mysql_real_escape_string 进行转义。 - gen_Eric
@Pekka,但我需要使用标记,这样我将失去标记,我什么都没做! - wfareed
1
@wfareed 你知道吗:防止XSS攻击需要对标签进行编码?同时你还需要使用类似markdown或BBCodes的工具。 - TimWolla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接