防止回显变量时的 XSS 攻击


Prevent from XSS attacks when echoing variables

当我

在PHP中回显变量时,我需要防止XSS攻击。

例如,假设我的数据库中有两个值,一个用于用户名,另一个是电子邮件地址。

$username
$email

所以现在我想在HTML中使用这些变量时防止 XSS 攻击。

我用htmlspecialchars()尝试过这样的事情 -

<h5>Editing User <?php echo '"<strong>'.htmlspecialchars($username, ENT_QUOTES, 'UTF-8').'"</strong> (<strong>'; echo htmlspecialchars($email, ENT_QUOTES, 'UTF-8').'</strong>)'; ?></h5>

这是从上面呈现HTMLPHP

<h5>Editing User <strong>test_user</strong> (<strong>example@gmail.com</strong>)</h5>

那么,有人可以告诉我这是我需要走的正确方法吗?如果不是这样,正确的方法是什么?

希望有人可以帮助我。谢谢。

首先,转义输出的正确方法是htmlentities,而不是htmlspecialchars
转义从变量、数据库或用户输入获得的所有输出。
这几乎是逃避XSS攻击所要做的所有事情。
您也可以考虑在适当的情况下使用strip_tags

给你:

<h5>
    Editing User <b><?=htmlentities($username)?></b> 
    (<b><?=htmlentities($email)?></b>)
</h5>
HTML

实体编码适用于放入 HTML 文档正文中的不受信任的数据,例如在标记内。它甚至适用于进入属性的不受信任的数据,特别是如果您对在属性周围使用引号很虔诚。但是,如果您将不受信任的数据放在任何地方的标记中,或者将事件处理程序属性(如 onmouseover)、CSS 内部或 URL 中,HTML 实体编码将不起作用。因此,即使您在任何地方都使用 HTML 实体编码方法,您仍然很可能容易受到 XSS 的攻击。您必须对要放入不受信任数据的 HTML 文档部分使用转义语法。这就是以下规则的全部内容。

更多信息在 OWASP 中。

使用htmlspecialchars的正确方法是这样的:

echo htmlspecialchars($string, ENT_QUOTES, 'UTF-8');

另外,请记住,用户可以发送类似"Jim onclick=alert('hi')"这样的用户名

如果你不用引号括起来 value 属性,你会得到类似的东西:

<input type="text" name="username" value=Jim onclick=alert('hi')>

始终在属性两边使用引号。即使它们不是用户输入的,也是一个很好的习惯。

<input type="text" name="username" value="<?php echo htmlspecialchars($_POST['username'], ENT_QUOTES, 'UTF-8'); ?>">

考虑到这些事情,在大多数情况下,您应该得到保障。但是,如果您想非常挑剔,请阅读我之前提到的OWASP文档,它真的很有帮助。

更新

关于htmlspecialcharshtmlentities似乎存在一些争议。我将总结一些我一直在阅读的内容,您可以选择两者中的任何一种:

UTF-7 问题

htmlspecialcharshtmlentities都容易受到臭名昭著的 UTF-7 问题的影响。它们都不支持这种编码。正如您可以在帖子底部提供的SO帖子的一些评论中读到的那样:

如果您的页面/浏览器容易受到 UTF-7 问题的影响,请htmlentities 不会比htmlspecialchars更能帮助你。两者 它们将插入 <的 UTF-7=">只是"安全"的 ASCII 字符并将它们传递。

解决方案:不要使用 UTF-7,并确保转义使用与文档相同的字符编码完成,以避免引号消失:在网页标题中建立与htmlspecialchars中使用的编码相同的编码(例如 UTF-8):

header('Content-Type: text/html; charset=utf-8');

如果您不指定第三个参数,htmlspecialchars将默认为 UTF-8(在 PHP 5.4/5.5 中),因此即使您忘记建立它,也应该是安全的。

查看这篇有趣的文章,讨论该主题(以及有关XSS的更多有用信息)。链接

htmlentities() vs. htmlspecialchars()

htmlspecialchars

  • 当不需要对所有具有HTML等效项的字符进行编码时使用它,最好使用htmlspecialchars,因为向客户端发送的代码较少。这不是一个可以掉以轻心的问题:发送的代码更少,网页更快。代码也比html实体生成的代码更具可读性。
  • 有时,您正在编写 XML 数据,并且不能在 XML 文件中使用 HTML 实体。

html实体

  • 当需要对所有字符进行编码时。如果您的网页使用 ASCII 或 LATIN-1 等编码,而不是 UTF-8。

检查我提供的文档和这个SO问题:

htmlentities() vs. htmlspecialchars()

htmlspecialchars vs htmlentities 当涉及 XSS 时

并选择最适合您的一种。