我通常通过执行以下操作来逃避用户输入:
htmlspecialchars($str,ENT_QUOTES,"UTF-8");
以及mysql_real_escape_string($str)
。
如何改进?到目前为止,我没有遇到任何问题,但我不确定。
谢谢。
答案 0 :(得分:2)
应对数据进行转义(清理)以进行存储并对其进行编码以供显示。数据永远不会进行编码以进行存储。您只想存储原始数据。请注意,转义不会改变原始数据,因为不存储转义字符;它们仅用于正确表示原始数据和命令语法之间的差异。
简而言之,您希望执行以下操作:
$data = $_POST['raw data'];
//Shorthand used; you all know what a query looks like.
mysql_query("INSERT " . mysql_real_escape_string($data));
$show = mysql_query("SELECT ...");
echo htmlentities($show);
// Note that htmlentities() is usually overzealous.
// htmlspecialchars() is enough the majority of the time.
// You also don't have to use ENT_QUOTES unless you are using single
// quotes to delimit input (or someone please correct me on this).
如果启用了魔术引号,您可能还需要从用户输入中删除斜杠。 stripslashes()
就足够了。
至于为何不对存储进行编码,请采用以下示例:
假设您有一个char(5)
的数据库字段。 html输入也是maxlength="5"
。如果用户输入“&&&&&&”,这可能完全有效,则将其存储为“&&”。当它被检索并显示给用户时,如果你没有编码,他们会看到“&&,”这是不正确的。如果你进行编码,他们会看到“& amp;&”,这也是不正确的。您不存储用户要存储的数据。您需要存储原始数据。
在用户想要存储特殊字符的情况下,这也成为问题。你如何处理这些存储?你没有。把它保存起来。
要防止sql注入,至少使用mysql_real_escape_string
进行转义输入,但建议使用带有PDO等DB包装器的预准备语句。找出哪一个效果最好,或自己编写(并彻底测试)。
要防御XSS(跨站点脚本),请在将用户输入显示回来之前对其进行编码。
答案 1 :(得分:1)
如果您只使用mysql_real_escape_string($str)
来避免sql注入,请确保始终在查询中为其添加单引号。
将不安全的输出解析到屏幕时,htmlspecialchars很好。
答案 2 :(得分:1)
对于数据库切换到PDO。 它更容易,也可以逃脱。