58

我有点困惑,PHP中有这么多函数,有的用这个,有的用那个。有些人使用: htmlspecialchars(), htmlentities(),strip_tags()

哪个是正确的,你们通常使用什么?

这是正确的吗(如果有的话,请给我一个更好的建议):

$var = mysql_real_escape_string(htmlentities($_POST['username']));

这条线可以防止MySQL注入和XSS攻击??

顺便说一句,除了 XSS 攻击和 MySQL 注入之外,我还有什么需要注意的吗?

编辑

总结:

如果我想将字符串插入数据库,我不需要使用htmlentities,只需使用mysql_real_escape_string. 显示数据时,使用htmlentities(),这就是你的意思吗?

总结:

  • mysql_real_escape_string插入数据库时​​使用
  • htmlentities()将数据输出到网页时使用
  • htmlspecialchars()什么时候用?
  • strip_tags()什么时候用?
  • addslashes()什么时候用?

有人可以填写问号吗?

4

8 回答 8

71
  • mysql_real_escape_string插入数据库时​​使用
  • htmlentities()将数据输出到网页时使用
  • htmlspecialchars()什么时候用?
  • strip_tags()什么时候用?
  • addslashes()什么时候用?

htmlspecialchars() 什么时候使用?

htmlspecialchars大致相同htmlentities。区别:字符编码。

两者都对用于打开标签等的控制字符进行编码,例如<,也对来自其他语言的字符进行编码,例如变音符号、欧元符号等。如果您的网站是 UTF,请使用,否则使用.>&htmlentitieshtmlspecialchars()htmlentities()

strip_tags() 什么时候使用?

htmlspecialchars/entities对特殊字符进行编码,因此它们被显示但不被解释strip_tags删除它们。

在实践中,这取决于您需要做什么。

一个例子:您编写了一个论坛,并为用户提供了一个文本字段,以便他们可以发布内容。恶意的只是尝试:

pictures of <a href="javascript:void(window.setInterval(function () {window.open('http://evil.com');}, 1000));">kittens</a> here

如果您不执行任何操作,则会显示该链接,并且单击该链接的受害者会收到大量弹出窗口。

如果您 htmlentity/htmlspecialchar 您的输出,文本将按原样存在。如果你 strip_tag 它,它只是删除标签并显示它:

pictures of kittens here

有时您可能想要混合,在其中留下一些标签,例如<b>strip_tags可以在其中留下某些标签)。这也是不安全的,所以最好使用一些成熟的库来对抗 XSS。

添加斜线

引用旧版本的 PHP 手册

在需要在数据库查询等中引用的字符之前返回带有反斜杠的字符串。这些字符是单引号 (')、双引号 (")、反斜杠 () 和 NUL(NULL字节)。

addlashes()的一个示例使用是当您将数据输入数据库时​​。例如,要将名称O'reilly插入数据库,您需要对其进行转义。强烈建议使用 DBMS 特定的转义函数(例如 MySQL 的 mysqli_real_escape_string() 或 PostgreSQL 的 pg_escape_string()),但是如果您使用的 DBMS 没有转义函数并且 DBMS 使用 \ 来转义特殊字符,您可以使用这个功能。

当前版本的措辞不同。

于 2009-07-30T13:02:02.753 回答
10

我想到了这个快速清单:

  • 始终使用 HTTPS,如果没有 HTTPS,您的网站是完全未加密的。不,客户端加密和发送它们是行不通的,想想看。无效的 HTTPS 证书也使您容易受到MITM攻击。如果您买不起证书,只需使用 Let's Encrypt。
  • 始终用于htmlspecialchars()PHP 代码的任何输出,即或包含用户输入。大多数模板引擎可以帮助您轻松地做到这一点。
  • 在您的中使用仅 HTTP 标志php.ini以防止脚本访问您的 cookie
  • 防止与会话相关的问题
    • PHPSESSID永远不要在 cookie 之外暴露用户的(会话 ID) ,如果有人知道其他人的会话 ID,他们可以简单地使用它来登录他们的帐户
    • 使用该功能要非常小心,Remember me可能会显示一些警告。
    • 用户登录时刷新会话 ID(或任何适当的)
    • 超时非活动会话
  • 永远不要信任 cookie,它可以随时由脚本/用户更改、删除、修改和创建
  • 防止与 SQL 相关的问题
    • 始终使用准备好的语句。准备好的语句导致用户输入单独传递并防止SQL 注入
    • 让你的代码在失败时抛出异常。有时您的 SQL 服务器可能由于某种原因而关闭,PDO默认情况下会忽略该错误,并在日志中记录警告。这会导致您从数据库获得的变量为空,具体取决于您的代码,这可能会导致安全问题。
    • 一些库喜欢PDO 模拟准备好的语句。把它关掉。
    • 在您的数据库中使用UTF-8编码,它允许您存储几乎任何字符并避免与编码相关的攻击
    • 切勿将任何内容连接到您的查询。类似的事情$myquery = "INSERT INTO mydb.mytable (title) VALUES(" . $user_input . ")"几乎意味着您面临 SQL 注入的巨大安全风险。
  • 以随机、无扩展名的文件名存储上传的文件。如果用户上传带有.php文件扩展名的文件,那么每当您的代码加载该文件时,它就会执行它,并使用户能够执行一些后端代码
  • 确保您不容易受到CSRF 攻击
  • 始终更新您的 PHP 副本以确保最新的安全补丁和性能改进
于 2016-06-16T01:24:17.857 回答
6

仅在数据进入需要对其进行编码的系统的位置对数据进行编码——否则您将遇到想要操作真实数据的情况。

对于 SQL 注入 - 使用如何防止 PHP 中的 SQL 注入中所述的绑定变量?(它谈论准备好的陈述,但它是为您提供保护的绑定,而不是准备)。

对于 XSS - 如果您在指定 HTML 或文本的位置写入 HTML。在生成文档时使用 htmlentities。我会避免以这种形式将数据存储在数据库中(除非可能在 CPU 性能/磁盘访问时间正在变成和问题的写入罕见读取系统中 - 然后我会有一个 raw_ 和一个 html_ 版本的列... 或者只是使用 memcached 或类似的)。

如果您让用户输入 URL,那么您需要更加小心,因为这javascript:do_evil()是一个将执行的有效 URI(例如,作为单击链接的 href 或(在某些浏览器中)刚刚加载的图像的 src)。

于 2009-07-30T11:09:05.940 回答
4

htmlspecialchars()&, ', ", <, 和>转换为 HTML 实体格式(&amp;,&quot;等)

htmlentities() 将所有适用的字符转换为它们的 HTML 实体格式。

strip_tags() 删除所有 HTML 和 PHP 标记。

两者都htmlspecialchars()采用htmlentities()可选参数,指示应如何处理引号。有关详细信息,请参阅 PHP 手册。

strip_tags()函数采用一个可选参数,指示不应剥离哪些标签。

 $var = strip_tags ($var, '<p><br />');

strip_tags()功能甚至会删除无效的 HTML 标签,这可能会导致问题。例如, strip_tags()将抽出它认为是 HTML 标记的所有代码,即使它的格式不正确,例如

<b I forgot to close the tag.
于 2011-04-13T16:24:54.607 回答
3

您只需要在插入数据库时​​使用 mysql_escape_string() 并在显示 HTML 时使用 htmlentites。如果您想防止简单的注入攻击,这就足够了,但毫无疑问,在开发 Web 应用程序时您应该注意许多其他安全问题,另一个主要问题是跨站点请求伪造。

于 2009-07-30T11:08:22.963 回答
2

将数据插入数据库或查询数据库时,我不会使用 htmlentities() 。如果您数据库中的数据存储为实体,则该数据仅对理解 html 实体的东西有用。

您必须对不同类型的输出使用不同的转义机制,例如 SQL - mysql_real_escape_string()、HTML - htmlentities()htmlspecialchars()、shell - escapeshellarg()。这是因为“危险”字符对于每个字符都是不同的 - 没有一种神奇的方法可以使任何数据对任何输出媒体都安全。

于 2009-07-30T11:11:13.673 回答
1

看看这个网站PHP Security Consortium。我发现它是一个很好的网站,可以全面了解 PHP 安全性(包括 SQL 注入和 XSS)。

于 2009-07-30T11:07:15.553 回答
1

我知道这是一个老问题,但现在投票最多的答案可能会误导初学者。

截至 2017 年

  1. 你永远不应该使用 mysql_real_escape_string。甚至 mysqli_real_escape_string 也太弱了,无法保护您的数据库免受 SQL 注入。取而代之的是,您应该使用 PDO 和类似的技术。(见那个指南

  2. XSS(这里我的意思是:strip_tags(), addslashes(), htmlspecialchars(), htmlentities()) - 这里投票最多的答案仍然是正确的,但我建议阅读这篇文章

于 2017-12-10T22:14:46.190 回答