我有点困惑,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()
何时使用?有人可以填写问号吗?
答案 0 :(得分:63)
插入数据库时使用的
- 将数据输出到网页时使用的
mysql_real_escape_string
htmlentities()
htmlspecialchars()
何时使用?strip_tags()
何时使用?addslashes()
何时使用?
htmlspecialchars
与htmlentities
大致相同。区别:字符编码。
两者都编码控制字符,如<
,>
,&
等用于打开标记等。htmlentities
也编码来自其他语言的字符,例如变形金刚,欧元 - 符号等。如果您的网站是UTF,请使用htmlspecialchars()
,否则请使用htmlentities()
。
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。
引用old version of the PHP manual:
在需要在数据库查询中引用的字符之前返回带有反斜杠的字符串。这些字符是单引号('),双引号(“),反斜杠()和NUL( NULL 字节)。
使用 addslashes()的一个示例是将数据输入数据库。例如,要将名称 O'reilly 插入数据库,您需要将其转义。强烈建议使用DBMS特定的转义函数(例如MySQL的mysqli_real_escape_string()或PostgreSQL的pg_escape_string()),但如果您使用的DBMS没有转义函数且DBMS使用\来转义特殊字符,那么可以使用这个功能。
current version措辞不同。
答案 1 :(得分:9)
我想到了这个快速清单:
htmlspecialchars()
,即包含用户输入。大多数模板引擎都可以帮助您轻松完成。php.ini
中使用仅HTTP标记以防止脚本访问您的Cookie PHPSESSID
(会话ID),如果有人知道其他人的会话ID,他们可以直接使用它登录他们的帐户Remember me
功能要非常小心,可能会显示一点警告。PDO
等库默认忽略该错误,并在日志中记录警告。这会导致从数据库获取的变量为空,具体取决于您的代码,这可能会导致安全问题。PDO
模拟准备好的语句。把它关掉。UTF-8
编码,它允许您存储几乎任何字符并避免与编码相关的攻击$myquery = "INSERT INTO mydb.mytable (title) VALUES(" . $user_input . ")"
之类的东西几乎意味着你有很大的SQL注入安全风险。.php
的文件,那么只要您的代码加载该文件,它就会执行该文件,并使用户能够执行某些后端代码答案 2 :(得分:6)
仅对数据进入需要编码的系统进行编码 - 否则您将遇到想要操纵实际数据的情况。
对于SQL注入 - 使用How can I prevent SQL injection in PHP?中描述的绑定变量(它讨论预准备语句,但它是为您提供保护而不是准备的绑定)。
对于XSS - 如果您在指定HTML或文本的位置写入HTML。在生成文档的位置使用htmlentities。我会避免以这种形式将数据存储在数据库中(除了可能在写入稀疏读取的系统中,CPU性能/磁盘访问时间正在变成并发出 - 然后我会有一个raw_和html_版本的列......或者只是使用memcached或类似的东西。)
如果您要让用户输入网址,那么您需要更加小心,因为javascript:do_evil()
是一个有效的URI(例如,作为点击链接的href或(在某些浏览器中)的src刚加载的图像。
答案 3 :(得分:4)
<强> htmlspecialchars()
强>
将&
,'
,"
,<
和>
转换为HTML实体格式(&
,"
等。)
<强> 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.
答案 4 :(得分:3)
在插入数据库时只需要使用mysql_escape_string(),在显示HTML时需要使用htmlentites。如果您想要防止简单的注入攻击,这就足够了,但毫无疑问,在开发Web应用程序时您应该注意许多其他安全问题,另一个主要问题是跨站点请求伪造。
答案 5 :(得分:2)
在将数据插入数据库或查询数据库时,我不会使用htmlentities()。如果您数据库中的数据存储为实体,那么该数据仅对理解html实体的内容有用。
您必须为不同类型的输出使用不同的转义机制,例如SQL - mysql_real_escape_string(),HTML - htmlentities()或htmlspecialchars(),shell - escapeshellarg()。这是因为“危险”的字符对于每个字符都是不同的 - 没有一种神奇的方法可以使任何数据对任何输出媒体都安全。
答案 6 :(得分:1)
查看此网站PHP Security Consortium。我发现它是一个很好的网站,可以全面了解PHP安全性(包括SQL注入和XSS)。
答案 7 :(得分:1)
我知道这是一个老问题,但现在投票最多的答案可能会误导初学者。
你永远不应该使用mysql_real_escape_string。甚至mysqli_real_escape_string也太弱,无法保护您的数据库免受SQL注入。而不是这个,你应该使用PDO和类似的技术。 (见that guide)
XSS(我的意思是:strip_tags()
,addslashes()
,htmlspecialchars()
,htmlentities()
) - 这里投票最多的答案仍然是正确的,但我建议阅读this article