PHP:有关用户输入如何“免疫”的建议

时间:2011-05-11 12:43:42

标签: php user-input sanitize

我通常通过执行以下操作来逃避用户输入:

htmlspecialchars($str,ENT_QUOTES,"UTF-8");

每当mysql连接可用时,

以及mysql_real_escape_string($str)

如何改进?到目前为止,我没有遇到任何问题,但我不确定。

谢谢。

3 个答案:

答案 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。 它更容易,也可以逃脱。

http://php.net/pdo