如果检索到的数据已被清理,是否需要从MySQL服务器转义输出?

时间:2016-02-01 18:10:42

标签: php mysql forms escaping

我很想知道,如果在用户提交表单时已经过滤了正在检索的数据,是否有必要从MySQL服务器转义输出。

例:
1.用户提交一个带有博客评论的表单 2.在表单提交时,在将数据发送到MySQL服务器之前,使用FILTER_SANITIZE_SPECIAL_CHARS过滤其输入以防止注入攻击 3.数据发布到服务器后,用户将被重新路由到另一个屏幕,在那里他们可以查看他们的评论 4.从服务器检索其注释(已存储已过滤的输入)时,是否还必须转义此输出?

这是我的主要问题。我正在从表单(用于博客文章)中获取用户输入,使用FILTER_SANITIZE_SPECIAL_CHARS对其进行清理,然后将其发布到MySQL服务器。如果我从服务器检索此信息并以html格式显示,则没有问题。但是,我一直在读,你应该总是逃避服务器的输出。所以我用htmlspecialchars()转发了同一个帖子。现在,我有一个问题,即所有特殊字符(包括括号,以及用户在其帖子中使用的任何引号)都以其转义的html格式返回。不是用户友好的。

最好的解决方法是什么,或者如果它来自服务器并且已经在用户输入上进行了清理,它是否甚至需要转义输出?

1 个答案:

答案 0 :(得分:4)

清理与转义相同,你应该确保不要混淆两者。

清理正在删除不需要的输入。也就是说,如果用户在其输入中添加了<script>标记,并且您不希望其输入包含<script>标记,则删除该<script>标记将进行清理。清理是转义输出上下文的数据。

转义正确编码输出上下文的数据。例如,为防止HTML注入,您可以致电htmlspecialchars()&正确编码为&amp;。为防止SQL注入,您可以使用mysqli::real_escape_string()'转换为\'。 (虽然使用预准备语句/参数化查询以防止不必担心sql注入或转义,但高度更可取。)

重要,转义是特定于上下文的。您用于HTML的转义不一定对SQL有效或足够(反之亦然,或任何其他输出上下文)。

FILTER_SANITIZE_SPECIAL_CHARS的问题在于它命名不佳:它只在一个步骤中执行,这会让您的数据库感到困惑(因为您的数据库现在有html编码的数据) ,并且输出容易混淆(因为现在你已经转义了很容易被多次转义的数据)。

相反,您应该明确区分您的清理和逃避工作。 清理您不想要保留的输入数据。 在输出上转义数据,并根据其正确的输出上下文。

您希望在数据库中存储原始(预输出转义)数据的原因是,如果您需要输出到不同的上下文(例如,现在您需要输出JSON输出,或者您需要把它写到一个文件,或实际看到原始数据是什么),你不需要首先解开它。 (如果你真的需要,你可以合理地将一个预先转发的副本存储在一个单独的列中,但是你应该始终可以获得原始数据。)它还使规则变得简单:始终清理输入;总是逃避输出。